return true;
}
}
- else if (is_gimple_call (stmt) && gimple_store_p (stmt))
+ else if (is_gimple_call (stmt)
+ && gimple_store_p (stmt)
+ && (gimple_call_builtin_p (stmt)
+ || gimple_call_internal_p (stmt)
+ || !aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
+ gimple_call_fntype (stmt))))
{
asan_mem_ref r;
asan_mem_ref_init (&r, NULL, 1);
return;
poly_int64 decl_size;
- if ((VAR_P (inner) || TREE_CODE (inner) == RESULT_DECL)
+ if ((VAR_P (inner)
+ || (TREE_CODE (inner) == RESULT_DECL
+ && !aggregate_value_p (inner, current_function_decl)))
&& offset == NULL_TREE
&& DECL_SIZE (inner)
&& poly_int_tree_p (DECL_SIZE (inner), &decl_size)
}
bool instrumented = false;
- if (gimple_store_p (stmt))
+ if (gimple_store_p (stmt)
+ && (gimple_call_builtin_p (stmt)
+ || gimple_call_internal_p (stmt)
+ || !aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
+ gimple_call_fntype (stmt))))
{
tree ref_expr = gimple_call_lhs (stmt);
instrument_derefs (iter, ref_expr,
}
/* { dg-output "ERROR: AddressSanitizer: heap-buffer-overflow.*(\n|\r\n|\r)" } */
-/* { dg-output " #0 0x\[0-9a-f\]+ +in A::A()" } */
+/* { dg-output " #0 0x\[0-9a-f\]+ +in (A::A\\\(\\\)|vnull::operator vec\\\(\\\).*(\n|\r\n|\r)" } */
+/* { dg-output " #1 0x\[0-9a-f\]+ +in A::A\\\(\\\))" } */
--- /dev/null
+/* PR sanitizer/112709 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=address -O2" } */
+
+struct S { char c[1024]; };
+int foo (int);
+
+__attribute__((returns_twice, noipa)) struct S
+bar (int x)
+{
+ (void) x;
+ struct S s = {};
+ s.c[42] = 42;
+ return s;
+}
+
+void
+baz (struct S *p)
+{
+ foo (1);
+ *p = bar (0);
+}
+
+void
+qux (int x, struct S *p)
+{
+ if (x == 25)
+ x = foo (2);
+ else if (x == 42)
+ x = foo (foo (3));
+ *p = bar (x);
+}
+
+void
+corge (int x, struct S *p)
+{
+ void *q[] = { &&l1, &&l2, &&l3, &&l3 };
+ if (x == 25)
+ {
+ l1:
+ x = foo (2);
+ }
+ else if (x == 42)
+ {
+ l2:
+ x = foo (foo (3));
+ }
+l3:
+ *p = bar (x);
+ if (x < 4)
+ goto *q[x & 3];
+}