aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2016-07-30 22:36:56 +0000
committerMartin Sebor <msebor@redhat.com>2016-07-30 22:36:56 +0000
commit840702abfd91688a699bf44703a289427b2b44b8 (patch)
tree550fac33b2921668ad6de96d6b6f2290e64f48de
parent2a120189c29cbfc84ca27d72fe47ae41911cd8fa (diff)
PR c++/60760 - arithmetic on null pointers should not be allowed in constant
PR c++/71091 - constexpr reference bound to a null pointer dereference gcc/cp/ChangeLog: PR c++/60760 PR c++/71091 * constexpr.c (cxx_eval_binary_expression): Reject invalid expressions involving null pointers. (cxx_eval_component_reference): Reject null pointer dereferences. (cxx_eval_indirect_ref): Reject indirecting through null pointers. (cxx_eval_constant_expression): Reject invalid expressions involving null pointers. gcc/testsuite/ChangeLog: PR c++/60760 PR c++/71091 * g++.dg/cpp0x/constexpr-cast.C: New test. * g++.dg/cpp0x/constexpr-nullptr-2.C: New test. * g++.dg/cpp1y/constexpr-sfinae.C: Correct. * g++.dg/ubsan/pr63956.C: Correct. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@238909 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/constexpr.c84
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C303
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C18
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr63956.C4
7 files changed, 435 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index db6e1eb7730..1037208d5bd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2016-07-30 Martin Sebor <msebor@redhat.com>
+
+ PR c++/60760
+ PR c++/71091
+ * constexpr.c (cxx_eval_binary_expression): Reject invalid expressions
+ involving null pointers.
+ (cxx_eval_component_reference): Reject null pointer dereferences.
+ (cxx_eval_indirect_ref): Reject indirecting through null pointers.
+ (cxx_eval_constant_expression): Reject invalid expressions involving
+ null pointers.
+
2016-07-29 Marek Polacek <polacek@redhat.com>
PR c/71926
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 58716892f71..8bda97373b1 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1848,6 +1848,13 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
else if (TREE_CODE (rhs) == PTRMEM_CST)
rhs = cplus_expand_constant (rhs);
}
+ if (code == POINTER_PLUS_EXPR && !*non_constant_p
+ && integer_zerop (lhs) && !integer_zerop (rhs))
+ {
+ if (!ctx->quiet)
+ error ("arithmetic involving a null pointer in %qE", lhs);
+ return t;
+ }
if (r == NULL_TREE)
r = fold_binary_loc (loc, code, type, lhs, rhs);
@@ -2195,6 +2202,11 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
tree whole = cxx_eval_constant_expression (ctx, orig_whole,
lval,
non_constant_p, overflow_p);
+ if (TREE_CODE (whole) == INDIRECT_REF
+ && integer_zerop (TREE_OPERAND (whole, 0))
+ && !ctx->quiet)
+ error ("dereferencing a null pointer in %qE", orig_whole);
+
if (TREE_CODE (whole) == PTRMEM_CST)
whole = cplus_expand_constant (whole);
if (whole == orig_whole)
@@ -2955,6 +2967,14 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
if (*non_constant_p)
return t;
+ if (!lval && integer_zerop (op0))
+ {
+ if (!ctx->quiet)
+ error ("dereferencing a null pointer");
+ *non_constant_p = true;
+ return t;
+ }
+
r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
&empty_base);
if (r == NULL_TREE)
@@ -3614,10 +3634,22 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (!flag_permissive || ctx->quiet)
*overflow_p = true;
}
+
+ if (TREE_CODE (t) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
+ && !integer_zerop (t))
+ {
+ if (!ctx->quiet)
+ error ("value %qE of type %qT is not a constant expression",
+ t, TREE_TYPE (t));
+ *non_constant_p = true;
+ }
+
return t;
}
- switch (TREE_CODE (t))
+ tree_code tcode = TREE_CODE (t);
+ switch (tcode)
{
case RESULT_DECL:
if (lval)
@@ -4041,7 +4073,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case NOP_EXPR:
case UNARY_PLUS_EXPR:
{
- enum tree_code tcode = TREE_CODE (t);
tree oldop = TREE_OPERAND (t, 0);
tree op = cxx_eval_constant_expression (ctx, oldop,
@@ -4067,15 +4098,48 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
return t;
}
}
- if (POINTER_TYPE_P (type)
- && TREE_CODE (op) == INTEGER_CST
- && !integer_zerop (op))
+
+ if (POINTER_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
{
- if (!ctx->quiet)
- error_at (EXPR_LOC_OR_LOC (t, input_location),
- "reinterpret_cast from integer to pointer");
- *non_constant_p = true;
- return t;
+ if (integer_zerop (op))
+ {
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (!ctx->quiet)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "dereferencing a null pointer");
+ *non_constant_p = true;
+ return t;
+ }
+ else if (TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
+ {
+ tree from = TREE_TYPE (op);
+
+ if (!can_convert (type, from, tf_none))
+ {
+ if (!ctx->quiet)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "conversion of %qT null pointer to %qT "
+ "is not a constant expression",
+ from, type);
+ *non_constant_p = true;
+ return t;
+ }
+ }
+ }
+ else
+ {
+ /* This detects for example:
+ reinterpret_cast<void*>(sizeof 0)
+ */
+ if (!ctx->quiet)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ "%<reinterpret_cast<%T>(%E)%> is not "
+ "a constant-expression",
+ type, op);
+ *non_constant_p = true;
+ return t;
+ }
}
if (op == oldop && tcode != UNARY_PLUS_EXPR)
/* We didn't fold at the top so we could check for ptr-int
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a2d5c8850b..a73a39defc6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2016-07-30 Martin Sebor <msebor@redhat.com>
+
+ PR c++/60760
+ PR c++/71091
+ * g++.dg/cpp0x/constexpr-cast.C: New test.
+ * g++.dg/cpp0x/constexpr-nullptr-2.C: New test.
+ * g++.dg/cpp1y/constexpr-sfinae.C: Correct.
+ * g++.dg/ubsan/pr63956.C: Correct.
+
2016-07-30 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/vec-extract-2.c: New tests for vec_extract of
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C
new file mode 100644
index 00000000000..8e11193be53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C
@@ -0,0 +1,24 @@
+// Test to verify that evaluating reinterpret_cast is diagnosed in
+// constant expressions.
+// { dg-do compile { target c++11 } }
+
+int i;
+
+// The following is accepted due to bug 49171.
+constexpr void *q = reinterpret_cast<void*>(&i); // { dg-error "" "bug c++/49171" { xfail *-*-*-* } }
+
+constexpr void *r0 = reinterpret_cast<void*>(1); // { dg-error "not a constant expression" }
+constexpr void *r1 = reinterpret_cast<void*>(sizeof 'x'); // { dg-error ".reinterpret_cast<void\\*>\\(1ul\\). is not a constant-expression" }
+
+template <class T>
+constexpr bool f ()
+{
+#if __cplusplus > 201103L
+ T *p = reinterpret_cast<T*>(sizeof (T));
+ return p;
+#else
+ return *reinterpret_cast<T*>(sizeof (T));
+#endif
+}
+
+constexpr bool b = f<int>(); // { dg-error "not a constant expression" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C
new file mode 100644
index 00000000000..aeea87c2ae7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C
@@ -0,0 +1,303 @@
+// PR c++/60760 - arithmetic on null pointers should not be allowed
+// in constant expressions
+// PR c++/71091 - constexpr reference bound to a null pointer dereference
+// accepted
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pointer-arith" }
+
+// Generate a null poiinter.
+constexpr int* null () { return 0; }
+
+// Test case from comment #0 in c++/60760.
+namespace PR_60760_comment_0 {
+
+constexpr int* ptr = nullptr;
+constexpr int* ptr2 = ptr + 1; // { dg-error "null pointer|not a constant" }
+
+}
+
+// Test case from comment #1 in c++/60760.
+namespace PR_60760_comment_1 {
+
+constexpr int* ptr = nullptr;
+
+constexpr int zero = 0;
+constexpr int* ptr2 = ptr + zero; // Adding zero is valid.
+constexpr int* ptr3 = ptr - zero; // As is subtracting zero.
+
+}
+
+// Test case from c++/71091.
+namespace PR_71091 {
+
+constexpr int *p = 0;
+constexpr const int &r = *p; // { dg-error "dereferencing a null pointer" }
+
+}
+
+// Other test cases.
+namespace C {
+
+struct S { int a, b[1]; } s;
+
+constexpr S *p0 = &s;
+constexpr S *p1 = nullptr;
+constexpr int *r0 = p1->b; // { dg-error "null pointer|constant expression" }
+
+// Adding and subtracting zero from and to a null pointer is valid.
+constexpr S* r1 = p1 + 0;
+constexpr S* r2 = r1 - 0;
+
+constexpr int zero = 0;
+
+constexpr S* r3 = r2 + zero;
+constexpr S* r4 = r3 - zero;
+
+static_assert (r4 == nullptr, "r4 == nullptr");
+
+constexpr const S *pcs = p0;
+constexpr int d1 = pcs - p0;
+constexpr int d2 = p0 - pcs;
+
+constexpr bool b = !p1 && !pcs;
+}
+
+namespace D {
+
+struct A { int i; const A *pa1; const A *pa0; };
+
+constexpr A a1 = { 0, 0, 0 };
+constexpr A a2 = { 1, &a1, 0 };
+
+constexpr const A *pa2 = &a2;
+constexpr int i0 = pa2->i;
+constexpr int i1 = pa2->pa1->i;
+constexpr int i2 = pa2->pa1->pa0->i; // { dg-error "null pointer|not a constant" }
+
+constexpr const A *pa3 = &*pa2->pa1->pa0;
+constexpr const A *pa4 = pa2->pa1->pa0 + 1; // { dg-error "null pointer|not a constant" }
+
+constexpr const int *pi0 = &pa2->pa1->pa0->i; // { dg-error "null pointer|not a constant" }
+
+constexpr const A *pa5 = 0;
+constexpr const int *pi1 = &pa5->i; // { dg-error "null pointer|not a constant" }
+
+}
+
+
+namespace SimpleTests {
+
+constexpr int* p0 = nullptr;
+constexpr int* q0 = p0;
+constexpr int* r0 = null ();
+
+// Conversion to cv-qualified void* is valid.
+constexpr void* pv0 = p0;
+constexpr const void* pv1 = p0;
+constexpr volatile void* pv2 = p0;
+constexpr const volatile void* pv3 = p0;
+constexpr void* pv4 = static_cast<void*>(p0);
+constexpr const void* pv5 = static_cast<const void*>(p0);
+
+// The following should be rejected but isn't because of bug c++/49171
+// - [C++0x][constexpr] Constant expressions support reinterpret_cast
+constexpr void* pv6 = reinterpret_cast<void*>(p0); // { dg-error "" "bug c++/49171" { xfail *-*-* } }
+
+// Adding or subtracting zero from a null pointer is valid in C++.
+constexpr int* p1 = p0 + 0;
+constexpr int* p2 = p0 - 0;
+constexpr int* p3 = 0 + p0;
+
+// While the text of the C++ standard still doesn't allow it, CWG
+// issue 232 implies that dererencing a null pointer is intended
+// to be permitted in contexts where the result isn't evaluated.
+// For compatibility with C that should at a minimum include
+// expressions like &*p that are valid there.
+constexpr int* p4 = &*p0;
+constexpr int* p5 = p0 + 1; // { dg-error "null pointer|not a constant" }
+constexpr int* p6 = 1 + p0; // { dg-error "null pointer|not a constant" }
+constexpr int* p7 = p0 - 1; // { dg-error "null pointer|not a constant" }
+constexpr int* p8 = &p0 [0];
+constexpr int* p9 = &0 [p0];
+
+constexpr int* p10 = null () + 2; // { dg-error "null pointer|not a constant" }
+constexpr int* p11 = 3 + null (); // { dg-error "null pointer|not a constant" }
+constexpr int* p12 = null () - 4; // { dg-error "null pointer|not a constant" }
+constexpr int* p13 = &null ()[4]; // { dg-error "null pointer|not a constant" }
+constexpr int* p14 = &3[null ()]; // { dg-error "null pointer|not a constant" }
+
+constexpr int* q1 = q0 + 0;
+constexpr int* q2 = q0 - 0;
+constexpr int* q3 = q0 + 1; // { dg-error "null pointer|not a constant" }
+constexpr int* q4 = q0 + 2; // { dg-error "null pointer|not a constant" }
+constexpr int* q5 = &q0 [0];
+
+// Subtracting null pointers from one another is valid.
+constexpr int i0 = p0 - (int*)0;
+constexpr int i1 = p0 - static_cast<int*>(0);
+constexpr int i2 = p0 - (int*)nullptr;
+constexpr int i3 = p0 - static_cast<int*>(nullptr);
+constexpr int i4 = p0 - p0;
+constexpr int i5 = p0 - q0;
+constexpr int i6 = p0 - r0;
+constexpr int i7 = (int*)0 - p0;
+constexpr int i8 = static_cast<int*>(0) - p0;
+constexpr int i9 = (int*)nullptr - p0;
+constexpr int i10 = static_cast<int*>(nullptr) - p0;
+constexpr int i11 = q0 - p0;
+constexpr int i12 = r0 - p0;
+
+}
+
+namespace IncompleteTypeTests {
+
+// The type must be complete.
+struct X;
+constexpr X *px0 = nullptr;
+constexpr X *px1 = px0 + 0; // { dg-error "invalid use of incomplete type" }
+constexpr X *px2 = px0 - 0; // { dg-error "invalid use of incomplete type" }
+constexpr X *px3 = px0 - px0; // { dg-error "invalid use of incomplete type" }
+
+constexpr void *pv0 = px0;
+constexpr void *pv1 = pv0;
+constexpr const void *pv2 = pv0;
+constexpr void *pv3 = pv2; // { dg-error "invalid conversion|not a constant expression" }
+constexpr const void *pv4 = pv2;
+
+constexpr X *px4 = pv0; // { dg-error "invalid conversion|not a constant expression" }
+
+}
+
+namespace IndirectTests {
+
+struct S { int i, j; struct SA { struct SB { int *pi; } sb; } sa; };
+
+constexpr S* ps = (S*)0;
+
+// Comparing null pointers is valid.
+constexpr bool b0 = ps == ps;
+constexpr bool b1 = ps != ps;
+constexpr bool b2 = ps < ps;
+constexpr bool b3 = ps <= ps;
+constexpr bool b4 = ps > ps;
+constexpr bool b5 = ps >= ps;
+
+constexpr bool b6 = ps == (S*)0;
+constexpr bool b7 = ps != (S*)0;
+constexpr bool b8 = ps < (S*)0;
+constexpr bool b9 = ps <= (S*)0;
+constexpr bool b10 = ps > (S*)0;
+constexpr bool b11 = ps >= (S*)0;
+
+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* pj0 = &((S*)0)->j; // { dg-error "not a constant expression" }
+constexpr int* pj1 = &((S*)nullptr)->j; // { dg-error "not a constant expression" }
+
+constexpr int* psi = &ps->i; // { dg-error "null pointer|not a constant" }
+constexpr int* psj = &ps->j; // { dg-error "null pointer|not a constant" }
+
+constexpr int* ps1i = &ps1->i; // { dg-error "null pointer|not a constant" }
+constexpr int* ps2i = &ps1->i; // { dg-error "null pointer|not a constant" }
+
+constexpr int* ps1j = &ps1->j; // { dg-error "null pointer|not a constant" }
+constexpr int* ps2j = &ps1->j; // { dg-error "null pointer|not a constant" }
+
+}
+
+namespace BaseAndDerivedTests {
+
+struct A { };
+struct B: A { };
+struct C: B { };
+struct D: B, C { }; // { dg-warning "inaccessible" }
+
+constexpr D *pd0 = 0;
+constexpr C *pc0 = 0;
+constexpr B *pb0 = 0;
+
+constexpr A *pa0 = pb0;
+constexpr A *pa1 = static_cast<A*>(pb0);
+constexpr A *pa2 = pc0;
+constexpr A *pa3 = pd0; // { dg-error "ambiguous base" }
+constexpr A *pa4 = static_cast<A*>(pd0); // { dg-error "ambiguous base" }
+
+constexpr B *pb1 = pa0; // { dg-error "invalid conversion|not a constant expression" }
+constexpr B *pb2 = static_cast<B*>(pa0); // { dg-error "not a constant expression" }
+
+constexpr C *pc1 = pa0; // { dg-error "invalid conversion|not a constant expression" }
+constexpr D *pd1 = pa0; // { dg-error "ambiguous base|invalid conversion" }
+
+struct E: private A { };
+
+constexpr E *pe0 = 0;
+constexpr A *pa5 = pe0; // { dg-error "inaccessible base of" }
+
+struct VA { virtual ~VA (); };
+struct VB: virtual VA { };
+struct VC: virtual VA { };
+struct VD: VB, VC { };
+
+constexpr VD *pvd0 = 0;
+constexpr VC *pvc0 = 0;
+constexpr VB *pvb0 = 0;
+
+constexpr VA *pva0 = pvb0;
+constexpr VA *pva1 = pvc0;
+constexpr VA *pva2 = pvd0;
+
+constexpr VB *pvb1 = pva0; // { dg-error "invalid conversion|cannot convert from pointer to base class" }
+
+}
+
+namespace FunctionTests {
+
+typedef void Func ();
+
+// Arithmetic on member function pointers is diagnosed with -Wpointer-arith.
+// With constexpr, only zero may be added or subtracted.
+constexpr Func *pf0 = 0;
+constexpr Func *pf1 = pf0 + 0; // triggers -Wpointer-arith
+constexpr Func *pf2 = pf0 - 0; // triggers -Wpointer-arith
+constexpr Func *pf3 = 0 + pf0; // triggers -Wpointer-arith
+constexpr Func *pf4 = pf0 + 1; // { dg-error "null pointer|not a constant" }
+constexpr Func *pf5 = 2 + pf0; // { dg-error "null pointer|not a constant" }
+constexpr Func *pf6 = pf0 - 3; // { dg-error "null pointer|not a constant" }
+
+struct S;
+typedef void (S::*MemFuncPtr)();
+
+// Arithmetic on member function pointers is rejected with a hard error.
+constexpr MemFuncPtr pmf0 = nullptr;
+constexpr MemFuncPtr pmf1 = pmf0 + 0; // { dg-error "invalid operands" }
+constexpr MemFuncPtr pmf2 = 0 + pmf0; // { dg-error "invalid operands" }
+constexpr MemFuncPtr pmf3 = pmf0 + 1; // { dg-error "invalid operands" }
+constexpr MemFuncPtr pmf4 = 1 + pmf0; // { dg-error "invalid operands" }
+constexpr MemFuncPtr pmf5 = pmf0 - 1; // { dg-error "invalid operands" }
+
+}
+
+namespace ConversionTest {
+
+struct A {
+ int *p;
+};
+
+constexpr const int* f (const int *p) { return p; }
+
+void f ()
+{
+ static_assert (!f (0), "f (a.p)");
+ static_assert (!f (nullptr), "f (a.p)");
+
+ constexpr A a = A ();
+
+ static_assert (!f (a.p), "f (a.p)");
+}
+
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C
index a83d7f4e1de..4a7deb8e826 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C
@@ -90,22 +90,28 @@ namespace NullPointerArithmetic {
constexpr int i = 0;
constexpr const int* a[] = { 0, &i };
-// Well-defined core constant expressoons involving null pointers.
+// Well-defined core constant expressions involving null pointers.
constexpr __PTRDIFF_TYPE__ d00 = a [0] - a [0];
constexpr __PTRDIFF_TYPE__ d11 = a [1] - a [1];
-// Undefined core constant expressoons involving null pointers.
+// Undefined core constant expressions involving null pointers.
// constexpr __PTRDIFF_TYPE__ d01 = a [0] - a [1];
// constexpr __PTRDIFF_TYPE__ d10 = a [1] - a [0];
-constexpr bool nullptr_sub_0 (int i, int j) { return 1 + a [i != 0] - a [j]; }
+// Valid when i == j.
+constexpr bool
+nullptr_sub_0 (bool i, bool j) { return 1 + a [!i] - a [!j]; }
-constexpr bool nullptr_sub_1 (int i, int j) { return 1 + a [i == 0] - a [j]; }
+// Valid when i != j.
+constexpr bool
+nullptr_sub_1 (bool i, bool j) { return 1 + a [i] - a [!j]; }
-template <int I>
+// Selected when I == 0.
+template <bool I>
constexpr int f (int (*)[nullptr_sub_0 (I, 0)] = 0) { return 0; }
-template <int I>
+// Selected when I != 0.
+template <bool I>
constexpr int f (int (*)[nullptr_sub_1 (I, 0)] = 0) { return 1; }
constexpr int n0 = f<0>();
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63956.C b/gcc/testsuite/g++.dg/ubsan/pr63956.C
index 25db8a40e52..ac01fa4fdd2 100644
--- a/gcc/testsuite/g++.dg/ubsan/pr63956.C
+++ b/gcc/testsuite/g++.dg/ubsan/pr63956.C
@@ -92,7 +92,7 @@ constexpr int
fn6 (const int &a, int b)
{
if (b != 2)
- b = a; // { dg-error "is not a constant expression" }
+ b = a;
return b;
}
@@ -106,7 +106,7 @@ fn7 (const int *a, int b)
constexpr int n1 = 7;
constexpr int n2 = fn7 (&n1, 5);
-constexpr int n3 = fn7 ((const int *) 0, 8);
+constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-error "null pointer" }
constexpr int
fn8 (int i)