Hi,

if I understand correctly the existing uses of tf_ignore_bad_quals, in order to correctly implement the resolution of CWG 1510, thus accept the testcases, we have to handle decltypes like references and template type arguments, thus make sure cp_build_qualified_type_real is called with | tf_ignore_bad_quals. The template case seems easy and I figured out a simple one-liner, in tsubst; the non-template case seems more tricky, because grokdeclarator sees just a reference, doesn't have the information that the type is coming from a decltype fully handled the first and only time through finish_decltype_type: in the tentative patch I resorted to an additional flag in cp_decl_specifier_seq... Patch passes testing, anyway.

Thanks,
Paolo.

////////////////////




Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h        (revision 217407)
+++ cp/cp-tree.h        (working copy)
@@ -4933,6 +4933,8 @@ typedef struct cp_decl_specifier_seq {
   BOOL_BITFIELD explicit_char_p : 1;
   /* True iff ds_thread is set for __thread, not thread_local.  */
   BOOL_BITFIELD gnu_thread_keyword_p : 1;
+  /* True iff the type is a decltype.  */
+  BOOL_BITFIELD decltype_p : 1;
 } cp_decl_specifier_seq;
 
 /* The various kinds of declarators.  */
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 217407)
+++ cp/decl.c   (working copy)
@@ -9421,7 +9421,8 @@ grokdeclarator (const cp_declarator *declarator,
 
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
-    (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
+    (type, type_quals, ((((typedef_decl && !DECL_ARTIFICIAL (typedef_decl))
+                         || declspecs->decltype_p)
                         ? tf_ignore_bad_quals : 0) | tf_warning_or_error));
   /* We might have ignored or rejected some of the qualifiers.  */
   type_quals = cp_type_quals (type);
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 217407)
+++ cp/parser.c (working copy)
@@ -14903,9 +14903,15 @@ cp_parser_simple_type_specifier (cp_parser* parser
     {
       type = token->u.value;
       if (decl_specs)
-       cp_parser_set_decl_spec_type (decl_specs, type,
-                                     token,
-                                     /*type_definition_p=*/false);
+       {
+         cp_parser_set_decl_spec_type (decl_specs, type,
+                                       token,
+                                       /*type_definition_p=*/false);
+         /* Remember that we are handling a decltype in order to
+            correctly implement the resolution of CWG 1510 when
+            its argument isn't instantiation dependent.  */
+         decl_specs->decltype_p = true;
+       }
       cp_lexer_consume_token (parser->lexer);
       return type;
     }
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 217407)
+++ cp/pt.c     (working copy)
@@ -12462,7 +12462,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
-                                            complain);
+                                            complain | tf_ignore_bad_quals);
       }
 
     case UNDERLYING_TYPE:
Index: testsuite/g++.dg/cpp0x/decltype61.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype61.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype61.C (working copy)
@@ -0,0 +1,20 @@
+// DR 1510, PR c++/60420
+// { dg-do compile { target c++11 } }
+
+struct MyIter
+{
+  int& operator*();
+};
+
+void foo(MyIter begin)
+{
+  auto x = [](const decltype(*begin)) { };
+}
+
+template<typename Iterator>
+void bar(Iterator begin)
+{
+  auto x = [](const decltype(*begin)) { };
+}
+
+template void bar<MyIter>(MyIter);

Reply via email to