+2018-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84463
+ * typeck.c (cp_build_addr_expr_1): Move handling of offsetof-like
+ tricks from here to ...
+ * cp-gimplify.c (cp_fold) <case ADDR_EXPR>: ... here. Only use it
+ if INDIRECT_REF's operand is INTEGER_CST cast to pointer type.
+
2018-04-18 Alexandre Oliva <aoliva@redhat.com>
PR c++/80290
goto unary;
case ADDR_EXPR:
+ loc = EXPR_LOCATION (x);
+ op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false);
+
+ /* Cope with user tricks that amount to offsetof. */
+ if (op0 != error_mark_node
+ && TREE_CODE (TREE_TYPE (op0)) != FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (op0)) != METHOD_TYPE)
+ {
+ tree val = get_base_address (op0);
+ if (val
+ && INDIRECT_REF_P (val)
+ && COMPLETE_TYPE_P (TREE_TYPE (val))
+ && TREE_CONSTANT (TREE_OPERAND (val, 0)))
+ {
+ val = TREE_OPERAND (val, 0);
+ STRIP_NOPS (val);
+ if (TREE_CODE (val) == INTEGER_CST)
+ return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0));
+ }
+ }
+ goto finish_unary;
+
case REALPART_EXPR:
case IMAGPART_EXPR:
rval_ops = false;
loc = EXPR_LOCATION (x);
op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
+ finish_unary:
if (op0 != TREE_OPERAND (x, 0))
{
if (op0 == error_mark_node)
return arg;
}
- /* ??? Cope with user tricks that amount to offsetof. */
- if (TREE_CODE (argtype) != FUNCTION_TYPE
- && TREE_CODE (argtype) != METHOD_TYPE
- && argtype != unknown_type_node
- && (val = get_base_address (arg))
- && COMPLETE_TYPE_P (TREE_TYPE (val))
- && INDIRECT_REF_P (val)
- && TREE_CONSTANT (TREE_OPERAND (val, 0)))
- {
- tree type = build_pointer_type (argtype);
- return fold_convert (type, fold_offsetof_1 (arg));
- }
-
/* Handle complex lvalues (when permitted)
by reduction to simpler cases. */
val = unary_complex_lvalue (ADDR_EXPR, arg);
+2018-04-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/84463
+ * g++.dg/cpp0x/constexpr-nullptr-1.C: Add -O1 to dg-options.
+ * g++.dg/cpp0x/constexpr-nullptr-2.C: Expect different diagnostics
+ in two cases. Uncomment two other tests and add expected dg-error for
+ them.
+ * g++.dg/init/struct2.C: Cast to int rather than long to avoid
+ -Wnarrowing diagnostics on some targets for c++11.
+ * g++.dg/parse/array-size2.C: Remove xfail.
+ * g++.dg/cpp0x/constexpr-84463.C: New test.
+
2018-04-17 Bill Schmidt <wschmidt@linux.ibm.com>
* gcc.target/powerpc/undef-bool-2.c: Add -mvsx.
--- /dev/null
+// PR c++/84463
+// { dg-do compile { target c++11 } }
+
+struct S { int r; const unsigned char s[5]; };
+static constexpr S a[] = { { 0, "abcd" } };
+struct T { const unsigned char s[5]; };
+static constexpr T b[] = { { "abcd" } };
+
+constexpr int
+foo (const unsigned char *x)
+{
+ return x[0];
+}
+
+constexpr static const S *j = &a[0];
+constexpr static const int k = j->s[0];
+constexpr static int l = foo (a[0].s);
+constexpr static int m = foo (j->s);
+constexpr static const T *n = &b[0];
+constexpr static const int o = n->s[0];
+constexpr static int p = foo (b[0].s);
+constexpr static int q = foo (n->s);
// c++/67376 on gcc-patches for additional background.
// { dg-do compile { target c++11 } }
-// { dg-options "-fdelete-null-pointer-checks -fdump-tree-optimized" }
+// { dg-options "-O1 -fdelete-null-pointer-checks -fdump-tree-optimized" }
// Runtime assert. Used for potentially invalid expressions.
#define RA(e) ((e) ? (void)0 : __builtin_abort ())
constexpr S* ps1 = ps;
constexpr S* ps2 = ps1;
-// The following aren't diagnosed due to a bug.
-// constexpr int* pi0 = &((S*)0)->i;
-// constexpr int* pi1 = &((S*)nullptr)->i;
+constexpr int* pi0 = &((S*)0)->i; // { dg-error "null pointer|not a constant" }
+constexpr int* pi1 = &((S*)nullptr)->i; // { dg-error "null pointer|not a constant" }
-constexpr int* pj0 = &((S*)0)->j; // { dg-error "not a constant expression" }
-constexpr int* pj1 = &((S*)nullptr)->j; // { dg-error "not a constant expression" }
+constexpr int* pj0 = &((S*)0)->j; // { dg-error "null pointer|not a constant" }
+constexpr int* pj1 = &((S*)nullptr)->j; // { dg-error "null pointer|not a constant" }
constexpr int* psi = &ps->i; // { dg-error "null pointer|not a constant" }
constexpr int* psj = &ps->j; // { dg-error "null pointer|not a constant" }
};
SaveLoadEntry trackEntries = {
- ((long) (__SIZE_TYPE__) (&((Track *) 42)->soundName[0])) - 42,
+ ((int) (__SIZE_TYPE__) (&((Track *) 42)->soundName[0])) - 42,
0, 1
};
saveLoadEntries(&trackEntries);
foo (void)
{
char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant" }
- char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "constant" "" { xfail *-*-* } }
+ char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "constant" }
bar (g, h);
}