Commit f7d86b5c by Martin Sebor Committed by Martin Sebor

builtins.c (compute_objsize): Add an argument and set it to offset into destination.


gcc/ChangeLog:

	* builtins.c (compute_objsize): Add an argument and set it to offset
	into destination.
	* builtins.h (compute_objsize): Add an argument.
	* tree-object-size.c (addr_object_size): Add an argument and set it
	to offset into destination.
	(compute_builtin_object_size): Same.
	* tree-object-size.h (compute_builtin_object_size): Add an argument.
	* tree-ssa-strlen.c (get_addr_stridx): Add an argument and set it
	to offset into destination.
	(maybe_warn_overflow): New function.
	(handle_store): Call maybe_warn_overflow to issue warnings.

gcc/testsuite/ChangeLog:

	* c-c++-common/Wstringop-overflow-2.c: Adjust text of expected messages.
	* g++.dg/warn/Wstringop-overflow-3.C: Same.
	* gcc.dg/Wstringop-overflow-17.c: Same.

From-SVN: r279248
parent c7f5b4ed
2019-12-11 Martin Sebor <msebor@redhat.com>
* builtins.c (compute_objsize): Add an argument and set it to offset
into destination.
* builtins.h (compute_objsize): Add an argument.
* tree-object-size.c (addr_object_size): Add an argument and set it
to offset into destination.
(compute_builtin_object_size): Same.
* tree-object-size.h (compute_builtin_object_size): Add an argument.
* tree-ssa-strlen.c (get_addr_stridx): Add an argument and set it
to offset into destination.
(maybe_warn_overflow): New function.
(handle_store): Call maybe_warn_overflow to issue warnings.
2019-12-11 Jozef Lawrynowicz <jozef.l@mittosystems.com> 2019-12-11 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* config/msp430/msp430.h (STARTFILE_SPEC) [!fexceptions]: Use * config/msp430/msp430.h (STARTFILE_SPEC) [!fexceptions]: Use
...@@ -3817,7 +3817,7 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */, ...@@ -3817,7 +3817,7 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */,
/* Only the two least significant bits are meaningful. */ /* Only the two least significant bits are meaningful. */
ostype &= 3; ostype &= 3;
if (compute_builtin_object_size (dest, ostype, &size, pdecl)) if (compute_builtin_object_size (dest, ostype, &size, pdecl, poff))
return build_int_cst (sizetype, size); return build_int_cst (sizetype, size);
if (TREE_CODE (dest) == SSA_NAME) if (TREE_CODE (dest) == SSA_NAME)
...@@ -3924,7 +3924,7 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */, ...@@ -3924,7 +3924,7 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */,
if (integer_zerop (size) if (integer_zerop (size)
&& *pdecl && DECL_P (*pdecl) && *pdecl && DECL_P (*pdecl)
&& *poff && integer_zerop (*poff)) && *poff && integer_zerop (*poff))
return integer_zero_node; return size_zero_node;
/* A valid offset into a declared object cannot be negative. */ /* A valid offset into a declared object cannot be negative. */
if (tree_int_cst_sgn (*poff) < 0) if (tree_int_cst_sgn (*poff) < 0)
......
...@@ -22,6 +22,12 @@ ...@@ -22,6 +22,12 @@
2019-12-11 Martin Sebor <msebor@redhat.com> 2019-12-11 Martin Sebor <msebor@redhat.com>
* c-c++-common/Wstringop-overflow-2.c: Adjust text of expected messages.
* g++.dg/warn/Wstringop-overflow-3.C: Same.
* gcc.dg/Wstringop-overflow-17.c: Same.
2019-12-11 Martin Sebor <msebor@redhat.com>
PR middle-end/79221 PR middle-end/79221
* gcc.dg/Wstringop-overflow-26.c: New test. * gcc.dg/Wstringop-overflow-26.c: New test.
......
...@@ -10,7 +10,7 @@ void sink (void*); ...@@ -10,7 +10,7 @@ void sink (void*);
struct Ax struct Ax
{ {
char n; char n;
char a[]; // { dg-message "destination object declared here" } char a[]; // { dg-message "declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
...@@ -91,7 +91,7 @@ void gaxx (void) ...@@ -91,7 +91,7 @@ void gaxx (void)
struct A0 struct A0
{ {
char n; char n;
char a[0]; // { dg-message "destination object declared here" } char a[0]; // { dg-message "declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
...@@ -158,7 +158,7 @@ void ga0x (void) ...@@ -158,7 +158,7 @@ void ga0x (void)
struct A1 struct A1
{ {
char n; char n;
char a[1]; // { dg-message "destination object declared here" } char a[1]; // { dg-message "declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
...@@ -256,7 +256,7 @@ void ga1x (void) ...@@ -256,7 +256,7 @@ void ga1x (void)
struct A1i struct A1i
{ {
char n; char n;
char a[1]; // { dg-message "destination object declared here" } char a[1]; // { dg-message "declared here" }
char x; char x;
}; };
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
{ dg-do compile } { dg-do compile }
{ dg-options "-O2 -Wall -Wno-array-bounds" } */ { dg-options "-O2 -Wall -Wno-array-bounds" } */
#define NOIPA __attribute__ ((noipa))
void sink (void*); void sink (void*);
// Exercise flexible array members. // Exercise flexible array members.
...@@ -10,13 +12,13 @@ void sink (void*); ...@@ -10,13 +12,13 @@ void sink (void*);
struct Ax struct Ax
{ {
char n; char n;
char a[]; // { dg-message "destination object declared here" } char a[]; // { dg-message "at offset \[0-2\] to object 'Ax::a' declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
Ax ax_; Ax ax_;
void gax_ () NOIPA void gax_ ()
{ {
ax_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
ax_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -27,7 +29,7 @@ void gax_ () ...@@ -27,7 +29,7 @@ void gax_ ()
// initialize the flexible array member. // initialize the flexible array member.
Ax ax0 = { 0 }; Ax ax0 = { 0 };
void gax0 () NOIPA void gax0 ()
{ {
ax0.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax0.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
ax0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -38,7 +40,7 @@ void gax0 () ...@@ -38,7 +40,7 @@ void gax0 ()
// initializes the flexible array member to empty. // initializes the flexible array member to empty.
Ax ax0_ = { 0, { } }; Ax ax0_ = { 0, { } };
void gax0_ () NOIPA void gax0_ ()
{ {
ax0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
ax0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -49,7 +51,7 @@ void gax0_ () ...@@ -49,7 +51,7 @@ void gax0_ ()
// an initializer. // an initializer.
Ax ax1 = { 1, { 0 } }; Ax ax1 = { 1, { 0 } };
void gax1 () NOIPA void gax1 ()
{ {
ax1.a[0] = 0; ax1.a[0] = 0;
ax1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } ax1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -58,7 +60,7 @@ void gax1 () ...@@ -58,7 +60,7 @@ void gax1 ()
Ax ax2 = { 2, { 1, 0 } }; Ax ax2 = { 2, { 1, 0 } };
void gax2 () NOIPA void gax2 ()
{ {
ax2.a[0] = 0; ax2.a[0] = 0;
ax2.a[1] = 0; ax2.a[1] = 0;
...@@ -67,7 +69,7 @@ void gax2 () ...@@ -67,7 +69,7 @@ void gax2 ()
// Verify no warning for an unknown struct object. // Verify no warning for an unknown struct object.
void gaxp (Ax *p) NOIPA void gaxp (Ax *p)
{ {
p->a[0] = 0; p->a[0] = 0;
p->a[3] = 0; p->a[3] = 0;
...@@ -79,7 +81,7 @@ void gaxp (Ax *p) ...@@ -79,7 +81,7 @@ void gaxp (Ax *p)
// initialized to any number of elements. // initialized to any number of elements.
extern Ax axx; extern Ax axx;
void gaxx () NOIPA void gaxx ()
{ {
axx.a[0] = 0; axx.a[0] = 0;
axx.a[3] = 0; axx.a[3] = 0;
...@@ -91,13 +93,13 @@ void gaxx () ...@@ -91,13 +93,13 @@ void gaxx ()
struct A0 struct A0
{ {
char n; char n;
char a[0]; // { dg-message "destination object declared here" } char a[0]; // { dg-message "at offset \[0-2\] to object 'A0::a' with size 0 declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
A0 a0_; A0 a0_;
void ga0_ () NOIPA void ga0_ ()
{ {
a0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
a0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -108,7 +110,7 @@ void ga0_ () ...@@ -108,7 +110,7 @@ void ga0_ ()
// initialize the flexible array member. // initialize the flexible array member.
A0 a00 = { 0 }; A0 a00 = { 0 };
void ga00 () NOIPA void ga00 ()
{ {
a00.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a00.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
a00.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a00.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -119,7 +121,7 @@ void ga00 () ...@@ -119,7 +121,7 @@ void ga00 ()
// initializes the flexible array member to empty. // initializes the flexible array member to empty.
A0 a00_ = { 0, { } }; A0 a00_ = { 0, { } };
void ga00_ () NOIPA void ga00_ ()
{ {
a00_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a00_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
a00_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a00_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -133,7 +135,7 @@ void ga00_ () ...@@ -133,7 +135,7 @@ void ga00_ ()
// Verify no warning for an unknown struct object. // Verify no warning for an unknown struct object.
void ga0p (A0 *p) NOIPA void ga0p (A0 *p)
{ {
p->a[0] = 0; p->a[0] = 0;
p->a[3] = 0; p->a[3] = 0;
...@@ -145,7 +147,7 @@ void ga0p (A0 *p) ...@@ -145,7 +147,7 @@ void ga0p (A0 *p)
// flexible array member) may not be initialized. // flexible array member) may not be initialized.
extern A0 a0x; extern A0 a0x;
void ga0x () NOIPA void ga0x ()
{ {
a0x.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a0x.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
a0x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a0x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -158,13 +160,13 @@ void ga0x () ...@@ -158,13 +160,13 @@ void ga0x ()
struct A1 struct A1
{ {
char n; char n;
char a[1]; // { dg-message "destination object declared here" } char a[1]; // { dg-message "at offset \[1-9\] to object 'A1::a' with size 1 declared here" }
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
A1 a1_; A1 a1_;
void ga1_ () NOIPA void ga1_ ()
{ {
a1_.a[0] = 0; a1_.a[0] = 0;
a1_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -175,7 +177,7 @@ void ga1_ () ...@@ -175,7 +177,7 @@ void ga1_ ()
// initialize the one-element array member. // initialize the one-element array member.
A1 a1__ = { 0 }; A1 a1__ = { 0 };
void ga1__ () NOIPA void ga1__ ()
{ {
a1__.a[0] = 0; a1__.a[0] = 0;
a1__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -186,7 +188,7 @@ void ga1__ () ...@@ -186,7 +188,7 @@ void ga1__ ()
// initializes the one-element array member to empty. // initializes the one-element array member to empty.
A1 a1_0 = { 0, { } }; A1 a1_0 = { 0, { } };
void ga1_0_ () NOIPA void ga1_0_ ()
{ {
a1_0.a[0] = 0; a1_0.a[0] = 0;
a1_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -197,7 +199,7 @@ void ga1_0_ () ...@@ -197,7 +199,7 @@ void ga1_0_ ()
// initializes the one-element array member. // initializes the one-element array member.
A1 a1_1 = { 0, { 1 } }; A1 a1_1 = { 0, { 1 } };
void ga1_1 () NOIPA void ga1_1 ()
{ {
a1_1.a[0] = 0; a1_1.a[0] = 0;
a1_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -206,7 +208,7 @@ void ga1_1 () ...@@ -206,7 +208,7 @@ void ga1_1 ()
// Verify no warning for an unknown struct object. // Verify no warning for an unknown struct object.
void ga1p (A1 *p) NOIPA void ga1p (A1 *p)
{ {
p->a[0] = 0; p->a[0] = 0;
p->a[3] = 0; p->a[3] = 0;
...@@ -219,7 +221,7 @@ void ga1p (A1 *p) ...@@ -219,7 +221,7 @@ void ga1p (A1 *p)
// a single element. // a single element.
extern A1 a1x; extern A1 a1x;
void ga1x () NOIPA void ga1x ()
{ {
a1x.a[0] = 0; a1x.a[0] = 0;
a1x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -232,14 +234,14 @@ void ga1x () ...@@ -232,14 +234,14 @@ void ga1x ()
struct A1i struct A1i
{ {
char n; char n;
char a[1]; // { dg-message "destination object declared here" } char a[1]; // { dg-message "at offset \[1-9\] to object 'A1i::a' with size 1 declared here" }
char x; char x;
}; };
// Verify warning for a definition with no initializer. // Verify warning for a definition with no initializer.
A1i a1i_; A1i a1i_;
void ga1i_ () NOIPA void ga1i_ ()
{ {
a1i_.a[0] = 0; a1i_.a[0] = 0;
a1i_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1i_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -250,7 +252,7 @@ void ga1i_ () ...@@ -250,7 +252,7 @@ void ga1i_ ()
// initialize the one-element array member. // initialize the one-element array member.
A1i a1i__ = { 0 }; A1i a1i__ = { 0 };
void ga1i__ () NOIPA void ga1i__ ()
{ {
a1i__.a[0] = 0; a1i__.a[0] = 0;
a1i__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1i__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -261,7 +263,7 @@ void ga1i__ () ...@@ -261,7 +263,7 @@ void ga1i__ ()
// initializes the one-element array member to empty. // initializes the one-element array member to empty.
A1 a1i_0 = { 0, { } }; A1 a1i_0 = { 0, { } };
void ga1i_0_ () NOIPA void ga1i_0_ ()
{ {
a1i_0.a[0] = 0; a1i_0.a[0] = 0;
a1i_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1i_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -272,7 +274,7 @@ void ga1i_0_ () ...@@ -272,7 +274,7 @@ void ga1i_0_ ()
// initializes the one-element array member. // initializes the one-element array member.
A1 a1i_1 = { 0, { 1 } }; A1 a1i_1 = { 0, { 1 } };
void ga1i_1 () NOIPA void ga1i_1 ()
{ {
a1i_1.a[0] = 0; a1i_1.a[0] = 0;
a1i_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1i_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -281,7 +283,7 @@ void ga1i_1 () ...@@ -281,7 +283,7 @@ void ga1i_1 ()
// Verify no warning for an unknown struct object. // Verify no warning for an unknown struct object.
void ga1ip (A1i *p) NOIPA void ga1ip (A1i *p)
{ {
p->a[0] = 0; p->a[0] = 0;
p->a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } p->a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -292,7 +294,7 @@ void ga1ip (A1i *p) ...@@ -292,7 +294,7 @@ void ga1ip (A1i *p)
// Verify no warning for an extern struct object. // Verify no warning for an extern struct object.
extern A1i a1ix; extern A1i a1ix;
void ga1ix () NOIPA void ga1ix ()
{ {
a1ix.a[0] = 0; a1ix.a[0] = 0;
a1ix.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } a1ix.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -305,7 +307,7 @@ void ga1ix () ...@@ -305,7 +307,7 @@ void ga1ix ()
struct Bx struct Bx
{ {
char n; char n;
char a[]; // { dg-message "destination object declared here" } char a[]; // { dg-message "at offset 0 to object 'Bx::a' declared here" }
// Verify the warning for a constant. // Verify the warning for a constant.
Bx () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } Bx () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
...@@ -315,13 +317,13 @@ struct Bx ...@@ -315,13 +317,13 @@ struct Bx
Bx (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } Bx (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
}; };
void gbx (void) NOIPA void gbx (void)
{ {
struct Bx bx; struct Bx bx;
sink (&bx); sink (&bx);
} }
void gbxi (int i) NOIPA void gbxi (int i)
{ {
struct Bx bxi (i); struct Bx bxi (i);
sink (&bxi); sink (&bxi);
...@@ -330,13 +332,13 @@ void gbxi (int i) ...@@ -330,13 +332,13 @@ void gbxi (int i)
struct B0 struct B0
{ {
char n; char n;
char a[0]; // { dg-message "destination object declared here" } char a[0]; // { dg-message "at offset 0 to object 'B0::a' with size 0 declared here" }
B0 () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } B0 () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
}; };
void gb0 (void) NOIPA void gb0 (void)
{ {
struct B0 b0; struct B0 b0;
sink (&b0); sink (&b0);
...@@ -346,12 +348,12 @@ void gb0 (void) ...@@ -346,12 +348,12 @@ void gb0 (void)
struct B1 struct B1
{ {
char n; char n;
char a[1]; // { dg-message "destination object declared here" } char a[1]; // { dg-message "at offset 1 to object 'B1::a' with size 1 declared here" }
B1 () { a[1] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } B1 () { a[1] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
}; };
void gb1 (void) NOIPA void gb1 (void)
{ {
struct B1 b1; struct B1 b1;
sink (&b1); sink (&b1);
...@@ -360,12 +362,12 @@ void gb1 (void) ...@@ -360,12 +362,12 @@ void gb1 (void)
struct B123 struct B123
{ {
char a[123]; // { dg-message "destination object declared here" } char a[123]; // { dg-message "at offset 123 to object 'B123::a' with size 123 declared here" }
B123 () { a[123] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } B123 () { a[123] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
}; };
void gb123 (void) NOIPA void gb123 (void)
{ {
struct B123 b123; struct B123 b123;
sink (&b123); sink (&b123);
...@@ -374,12 +376,12 @@ void gb123 (void) ...@@ -374,12 +376,12 @@ void gb123 (void)
struct B234 struct B234
{ {
char a[234]; // { dg-message "destination object declared here" } char a[234]; // { dg-message "at offset 234 to object 'B234::a' with size 234 declared here" }
B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
}; };
void g234 (void) NOIPA void g234 (void)
{ {
struct B234 b234 (234); struct B234 b234 (234);
sink (&b234); sink (&b234);
......
...@@ -13,7 +13,7 @@ void sink (void*); ...@@ -13,7 +13,7 @@ void sink (void*);
void call_copy_n (const char *s) void call_copy_n (const char *s)
{ {
char a[3]; // { dg-message "destination object declared here" } char a[3]; // { dg-message "declared here" }
copy_n (a, "1234567", 7); copy_n (a, "1234567", 7);
sink (a); sink (a);
} }
...@@ -55,7 +55,7 @@ static const unsigned HOST_WIDE_INT unknown[4] = { ...@@ -55,7 +55,7 @@ static const unsigned HOST_WIDE_INT unknown[4] = {
static tree compute_object_offset (const_tree, const_tree); static tree compute_object_offset (const_tree, const_tree);
static bool addr_object_size (struct object_size_info *, static bool addr_object_size (struct object_size_info *,
const_tree, int, unsigned HOST_WIDE_INT *, const_tree, int, unsigned HOST_WIDE_INT *,
tree * = NULL); tree * = NULL, tree * = NULL);
static unsigned HOST_WIDE_INT alloc_object_size (const gcall *, int); static unsigned HOST_WIDE_INT alloc_object_size (const gcall *, int);
static tree pass_through_call (const gcall *); static tree pass_through_call (const gcall *);
static void collect_object_sizes_for (struct object_size_info *, tree); static void collect_object_sizes_for (struct object_size_info *, tree);
...@@ -174,13 +174,15 @@ compute_object_offset (const_tree expr, const_tree var) ...@@ -174,13 +174,15 @@ compute_object_offset (const_tree expr, const_tree var)
static bool static bool
addr_object_size (struct object_size_info *osi, const_tree ptr, addr_object_size (struct object_size_info *osi, const_tree ptr,
int object_size_type, unsigned HOST_WIDE_INT *psize, int object_size_type, unsigned HOST_WIDE_INT *psize,
tree *pdecl /* = NULL */) tree *pdecl /* = NULL */, tree *poff /* = NULL */)
{ {
tree pt_var, pt_var_size = NULL_TREE, var_size, bytes; tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
tree dummy; tree dummy_decl, dummy_off = size_zero_node;
if (!pdecl) if (!pdecl)
pdecl = &dummy; pdecl = &dummy_decl;
if (!poff)
poff = &dummy_off;
gcc_assert (TREE_CODE (ptr) == ADDR_EXPR); gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
...@@ -201,7 +203,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, ...@@ -201,7 +203,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
|| TREE_CODE (TREE_OPERAND (pt_var, 0)) != SSA_NAME) || TREE_CODE (TREE_OPERAND (pt_var, 0)) != SSA_NAME)
{ {
compute_builtin_object_size (TREE_OPERAND (pt_var, 0), compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
object_size_type & ~1, &sz, pdecl); object_size_type & ~1, &sz, pdecl, poff);
} }
else else
{ {
...@@ -376,6 +378,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, ...@@ -376,6 +378,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
bytes = size_zero_node; bytes = size_zero_node;
else else
bytes = size_binop (MINUS_EXPR, var_size, bytes); bytes = size_binop (MINUS_EXPR, var_size, bytes);
*poff = bytes;
} }
if (var != pt_var if (var != pt_var
&& pt_var_size && pt_var_size
...@@ -390,6 +393,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, ...@@ -390,6 +393,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
bytes2 = size_zero_node; bytes2 = size_zero_node;
else else
bytes2 = size_binop (MINUS_EXPR, pt_var_size, bytes2); bytes2 = size_binop (MINUS_EXPR, pt_var_size, bytes2);
*poff = size_binop (PLUS_EXPR, *poff, bytes2);
bytes = size_binop (MIN_EXPR, bytes, bytes2); bytes = size_binop (MIN_EXPR, bytes, bytes2);
} }
} }
...@@ -496,10 +500,16 @@ pass_through_call (const gcall *call) ...@@ -496,10 +500,16 @@ pass_through_call (const gcall *call)
bool bool
compute_builtin_object_size (tree ptr, int object_size_type, compute_builtin_object_size (tree ptr, int object_size_type,
unsigned HOST_WIDE_INT *psize, unsigned HOST_WIDE_INT *psize,
tree *pdecl /* = NULL */) tree *pdecl /* = NULL */, tree *poff /* = NULL */)
{ {
gcc_assert (object_size_type >= 0 && object_size_type <= 3); gcc_assert (object_size_type >= 0 && object_size_type <= 3);
tree dummy_decl, dummy_off = size_zero_node;
if (!pdecl)
pdecl = &dummy_decl;
if (!poff)
poff = &dummy_off;
/* Set to unknown and overwrite just before returning if the size /* Set to unknown and overwrite just before returning if the size
could be determined. */ could be determined. */
*psize = unknown[object_size_type]; *psize = unknown[object_size_type];
...@@ -508,7 +518,7 @@ compute_builtin_object_size (tree ptr, int object_size_type, ...@@ -508,7 +518,7 @@ compute_builtin_object_size (tree ptr, int object_size_type,
init_offset_limit (); init_offset_limit ();
if (TREE_CODE (ptr) == ADDR_EXPR) if (TREE_CODE (ptr) == ADDR_EXPR)
return addr_object_size (NULL, ptr, object_size_type, psize, pdecl); return addr_object_size (NULL, ptr, object_size_type, psize, pdecl, poff);
if (TREE_CODE (ptr) != SSA_NAME if (TREE_CODE (ptr) != SSA_NAME
|| !POINTER_TYPE_P (TREE_TYPE (ptr))) || !POINTER_TYPE_P (TREE_TYPE (ptr)))
...@@ -533,11 +543,12 @@ compute_builtin_object_size (tree ptr, int object_size_type, ...@@ -533,11 +543,12 @@ compute_builtin_object_size (tree ptr, int object_size_type,
if (tree_fits_shwi_p (offset) if (tree_fits_shwi_p (offset)
&& compute_builtin_object_size (ptr, object_size_type, && compute_builtin_object_size (ptr, object_size_type,
psize, pdecl)) psize, pdecl, poff))
{ {
/* Return zero when the offset is out of bounds. */ /* Return zero when the offset is out of bounds. */
unsigned HOST_WIDE_INT off = tree_to_shwi (offset); unsigned HOST_WIDE_INT off = tree_to_shwi (offset);
*psize = off < *psize ? *psize - off : 0; *psize = off < *psize ? *psize - off : 0;
*poff = offset;
return true; return true;
} }
} }
......
...@@ -23,6 +23,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -23,6 +23,6 @@ along with GCC; see the file COPYING3. If not see
extern void init_object_sizes (void); extern void init_object_sizes (void);
extern void fini_object_sizes (void); extern void fini_object_sizes (void);
extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *, extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *,
tree * = NULL); tree * = NULL, tree * = NULL);
#endif // GCC_TREE_OBJECT_SIZE_H #endif // GCC_TREE_OBJECT_SIZE_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment