#include "attribs.h"
#include "tree-vector-builder.h"
#include "vec-perm-indices.h"
+#include "asan.h"
/* Nonzero if we are folding constants inside an initializer; zero
otherwise. */
tree arg00 = TREE_OPERAND (arg0, 0);
tree arg01 = TREE_OPERAND (arg0, 1);
- return fold_build_pointer_plus_loc
- (loc, fold_convert_loc (loc, type, arg00), arg01);
+ /* If -fsanitize=alignment, avoid this optimization in GENERIC
+ when the pointed type needs higher alignment than
+ the p+ first operand's pointed type. */
+ if (!in_gimple_form
+ && sanitize_flags_p (SANITIZE_ALIGNMENT)
+ && (min_align_of_type (TREE_TYPE (type))
+ > min_align_of_type (TREE_TYPE (TREE_TYPE (arg00)))))
+ return NULL_TREE;
+
+ arg00 = fold_convert_loc (loc, type, arg00);
+ return fold_build_pointer_plus_loc (loc, arg00, arg01);
}
/* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
--- /dev/null
+// PR c++/98206
+// { dg-do run }
+// { dg-options "-fsanitize=alignment -std=c++11 -fno-sanitize-recover=alignment" }
+
+template <typename Derived>
+struct Base1
+{
+ char c1;
+};
+
+template <typename Derived>
+struct Base2
+{
+ char c2;
+ const Derived &get2 () const { return static_cast<const Derived &> (*this); }
+};
+
+struct X : public Base1<X>, public Base2<X>
+{
+ X (const char *d) : data{d} {}
+ const char *data;
+};
+
+int
+main ()
+{
+ X x = X{"cheesecake"};
+ const char *p = x.get2 ().data;
+ if (p[0] != 'c')
+ __builtin_abort ();
+}