[RFH / Patch] C++/52282

Paolo Carlini paolo.carlini@oracle.com
Sat May 5 10:39:00 GMT 2012


Hi,

I'm analyzing this PR and the various testcases which come with it. It 
looks like we have indeed two separate issues: one, which looks simpler, 
with decltype, leading to ICEs; a more complex one with constexpr. The 
former is about ADDR_EXPR unhandled in the finish_decltype_type switch 
for this testcase:

template <typename T, T V>
struct C
{
static constexpr decltype(V) c() { return V; }
};

struct D
{
static constexpr int d() { return 10; }
};

static_assert((C<int(*)(), &D::d>::c())() == 10, "oops");

Would it make sense to just handle ADDR_EXPR too like in the patchlet 
below? It seems we are in this case too in the same situation which led 
to handling INTEGER_CST and PTRMEM_CST, or we have an issue with 
const-ness?

The problems with constexpr look more nasty, are all about testcases 
similar to the above, many variants of it, like:

template <typename T, T V>
struct B
{
typedef T type;
static constexpr type b() { return V; }
};

struct D
{
static constexpr int d() { return 10; }
};

static_assert((B<int(*)(), &D::d>::b())() == 10, "oops");

which is rejected like:

52282.C:32:1: error: non-constant condition for static assertion
static_assert((B<int(*)(), &D::d>::b())() == 10, "oops"); // line 30

52282.C:32:38: error: expression ‘D::d’ does not designate a constexpr 
function
static_assert((B<int(*)(), &D::d>::b())() == 10, "oops"); // line 30

For this kind of testcase I see a lot of NOP_EXPRs around, which I don't 
really understand and *appear* to confuse quite a bit code we have in 
the cxx_eval_* functions. For example, for the above, one crops up at 
the beginning of cxx_eval_call_expression:

if (TREE_CODE (fun) != FUNCTION_DECL)
{
/* Might be a constexpr function pointer. */
fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant,
/*addr*/false, non_constant_p);
if (TREE_CODE (fun) == ADDR_EXPR)
fun = TREE_OPERAND (fun, 0);
}

as the fun returned by cxx_eval_constant_expression and the logic 
handling ADDR_EXPR doesn't seem to work as designed. If I force a 
STRIP_NOPS the testcase is "accepted". But really I see something 
brittle about all these NOP_EXPRs and I'm looking for comments / hints. 
I don't think we just want to add STRIP_NOPS in a ton of places, which, 
if I understand correctly, would probably also imply the need to 
unshare_expr, but I don't have brilliant ideas right now...

Another kind of weird issue we are facing is for:

template <typename T, T V>
struct W_ { static constexpr T value = V; };

constexpr struct C {
constexpr int c1() const { return 10; }
} c;

static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops");

which leads to:

ice.cpp:72:1: error: non-constant condition for static assertion
static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops");

ice.cpp:72:56: error: expression ‘0u’ does not designate a constexpr 
function
static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops");

note the '0u'! (the error message comes from the beginning of 
cxx_eval_call_expression) I guess these issues should not require major 
surgeries if a testcase like the latter but using, instead of W_:

template <typename T, T V>
struct W { static constexpr T value() { return V; } };

works fine. In this case too, if I follow the long chain of cxx_eval_* I 
see a lot of NOP_EXPRs, but I'm not sure it's all there is to the issue, 
maybe we are just doing something wrong with the pointers...

Thanks for any comment!
Paolo.




-------------- next part --------------
Index: semantics.c
===================================================================
--- semantics.c	(revision 187192)
+++ semantics.c	(working copy)
@@ -5268,6 +5268,7 @@ finish_decltype_type (tree expr, bool id_expressio
 
         case INTEGER_CST:
 	case PTRMEM_CST:
+	case ADDR_EXPR:
           /* We can get here when the id-expression refers to an
              enumerator or non-type template parameter.  */
           type = TREE_TYPE (expr);


More information about the Gcc-patches mailing list