if (VOID_TYPE_P (type))
return void_node;
+ if (TREE_CODE (t) == CONVERT_EXPR
+ && ARITHMETIC_TYPE_P (type)
+ && INDIRECT_TYPE_P (TREE_TYPE (op)))
+ {
+ if (!ctx->quiet)
+ error_at (loc,
+ "conversion from pointer type %qT to arithmetic type "
+ "%qT in a constant expression", TREE_TYPE (op), type);
+ *non_constant_p = true;
+ return t;
+ }
+
if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
op = cplus_expand_constant (op);
non_constant_p = true;
}
- /* Technically we should check this for all subexpressions, but that
- runs into problems with our internal representation of pointer
- subtraction and the 5.19 rules are still in flux. */
- if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
- && ARITHMETIC_TYPE_P (TREE_TYPE (r))
- && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
- {
- if (!allow_non_constant)
- error ("conversion from pointer type %qT "
- "to arithmetic type %qT in a constant expression",
- TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
- non_constant_p = true;
- }
if (!non_constant_p && overflow_p)
non_constant_p = true;
--- /dev/null
+// PR c++/95307
+// { dg-do compile { target c++11 } }
+
+int v;
+constexpr auto p{reinterpret_cast<__UINTPTR_TYPE__>(&v) - 1u}; // { dg-error "conversion from pointer type" }
--- /dev/null
+// PR c++/82304
+// { dg-do compile { target c++14 } }
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+constexpr const char *
+foo (const char *p)
+{
+ auto l = reinterpret_cast<uintptr_t>(p); // { dg-error "conversion from pointer" }
+ ++l;
+ return reinterpret_cast<const char *>(l);
+}
+
+constexpr auto s = foo ("Hello");
constexpr int p = 1;
constexpr __PTRDIFF_TYPE__ bar (int a)
{
- return ((__PTRDIFF_TYPE__) &p) << a; // { dg-error "is not a constant expression" }
+ return ((__PTRDIFF_TYPE__) &p) << a; // { dg-error "conversion from pointer" }
}
constexpr __PTRDIFF_TYPE__ r = bar (2); // { dg-message "in .constexpr. expansion of" }
-constexpr __PTRDIFF_TYPE__ s = bar (0); // { dg-error "conversion from pointer" }
+constexpr __PTRDIFF_TYPE__ s = bar (0);
static int a, b;
lab1:
lab2:
- A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c; // { dg-error "not a constant integer" }
- A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d;
- A<(intptr_t)&a - (intptr_t)&b> e; // { dg-error "is not a constant expression" }
- A<(intptr_t)&a - (intptr_t)&a> f;
- A<(intptr_t)sizeof(a) + (intptr_t)&a> g; // { dg-error "not a constant integer" }
+ A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c; // { dg-error "conversion from pointer type" }
+ A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d; // { dg-error "conversion from pointer type" }
+ A<(intptr_t)&a - (intptr_t)&b> e; // { dg-error "conversion from pointer type" }
+ A<(intptr_t)&a - (intptr_t)&a> f; // { dg-error "conversion from pointer type" }
+ A<(intptr_t)sizeof(a) + (intptr_t)&a> g; // { dg-error "conversion from pointer type" }
A<(intptr_t)&a> h; // { dg-error "conversion from pointer type" }
}