Hi,

On 26/10/18 17:18, Jason Merrill wrote:
On Fri, Oct 26, 2018 at 4:52 AM Paolo Carlini <paolo.carl...@oracle.com> wrote:
On 24/10/18 22:41, Jason Merrill wrote:
On 10/15/18 12:45 PM, Paolo Carlini wrote:
         && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE
+       && TREE_CODE (declspecs->type) != DECLTYPE_TYPE
          && MAYBE_CLASS_TYPE_P (declspecs->type))
I would think that the MAYBE_CLASS_TYPE_P here should be CLASS_TYPE_P,
and then we can remove the TYPENAME_TYPE check.  Or do we want to
allow template type parameters for some reason?
Indeed, it would be nice to just use OVERLOAD_TYPE_P. However it seems
we at least want to let through TEMPLATE_TYPE_PARMs representing 'auto'
- otherwise Dodji's check a few lines below which fixed c++/51473
doesn't work anymore - and also BOUND_TEMPLATE_TEMPLATE_PARM, otherwise
we regress on template/spec32.C and template/ttp22.C because we don't
diagnose the shadowing anymore. Thus, I would say either we keep on
using MAYBE_CLASS_TYPE_P or we pick what we need, possibly we add a comment?
Aha.  I guess the answer is not to restrict that test any more, but
instead to fix the code further down so it gives a proper diagnostic
rather than call warn_misplaced_attr_for_class_type.

I see. Thus something like the below? It passes testing on x86_64-linux.

Thanks! Paolo.

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

Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 265510)
+++ cp/decl.c   (working copy)
@@ -4798,9 +4798,10 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
     declared_type = declspecs->type;
   else if (declspecs->type == error_mark_node)
     error_p = true;
-  if (declared_type == NULL_TREE && ! saw_friend && !error_p)
+  if ((!declared_type || TREE_CODE (declared_type) == DECLTYPE_TYPE)
+      && ! saw_friend && !error_p)
     permerror (input_location, "declaration does not declare anything");
-  else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
+  else if (declared_type && type_uses_auto (declared_type))
     {
       error_at (declspecs->locations[ds_type_spec],
                "%<auto%> can only be specified for variables "
@@ -4884,7 +4885,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
                  "%<constexpr%> cannot be used for type declarations");
     }
 
-  if (declspecs->attributes && warn_attributes && declared_type)
+  if (declspecs->attributes && warn_attributes && declared_type
+      && TREE_CODE (declared_type) != DECLTYPE_TYPE)
     {
       location_t loc;
       if (!CLASS_TYPE_P (declared_type)
Index: testsuite/g++.dg/cpp0x/decltype-33838.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype-33838.C     (revision 265510)
+++ testsuite/g++.dg/cpp0x/decltype-33838.C     (working copy)
@@ -2,5 +2,5 @@
 // PR c++/33838
 template<typename T> struct A
 {
-  __decltype (T* foo()); // { dg-error "expected|no arguments|accept" }
+  __decltype (T* foo()); // { dg-error "expected|no arguments|declaration" }
 };
Index: testsuite/g++.dg/cpp0x/decltype68.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype68.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/decltype68.C (working copy)
@@ -0,0 +1,7 @@
+// PR c++/84644
+// { dg-do compile { target c++11 } }
+
+template<int a>
+struct b {
+  decltype(a) __attribute__((break));  // { dg-error "declaration does not 
declare anything" }
+};

Reply via email to