In this testcase, since one of the overloads takes a pointer, we need to
check whether the argument is a valid null pointer constant. In C++11
only an integer literal can be a null pointer constant of integral type,
but in C++03 we need to handle other integer constant expressions. Here
we were passing the call expression into value_dependent_expression_p,
but in C++03 mode that function expects its argument to be a constant
expression, and the expression wasn't filtered out by
potential_constant_expression. The simplest solution is to just check
TREE_SIDE_EFFECTS since in C++03 mode an expression with side-effects
can't be a constant expression (unlike in C++11, where constexpr
function substitution can produce a constant expression from one with
TREE_SIDE_EFFECTS).
Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
commit bd25166552f6aa94b8da3ffea0201213e8057b17
Author: Jason Merrill <ja...@redhat.com>
Date: Mon May 13 13:34:31 2013 -0400
PR c++/56998
* call.c (null_ptr_cst_p): An expression with side-effects can't
be a C++03 null pointer constant.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index bd8f531..9f3a50d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -554,7 +554,7 @@ null_ptr_cst_p (tree t)
if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
/* Core issue 903 says only literal 0 is a null pointer constant. */
- if (cxx_dialect < cxx0x)
+ if (cxx_dialect < cxx0x && !TREE_SIDE_EFFECTS (t))
t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none));
STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t))
diff --git a/gcc/testsuite/g++.dg/template/overload13.C b/gcc/testsuite/g++.dg/template/overload13.C
new file mode 100644
index 0000000..d41ccd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/overload13.C
@@ -0,0 +1,16 @@
+// PR c++/56998
+
+class Secret;
+char IsNullLiteralHelper(Secret* p);
+char (&IsNullLiteralHelper(...))[2];
+
+struct C
+{
+ int val() { return 42; }
+};
+
+template <typename T>
+unsigned f()
+{
+ return sizeof(IsNullLiteralHelper(C().val()));
+}