On 02/08/2018 04:52 PM, Martin Sebor wrote:
I took me a while to find DECL_TEMPLATE_RESULT.  Hopefully
that's the right way to get the primary from a TEMPLATE_DECL.

Yes.

Attached is an updated patch.  It hasn't gone through full
testing yet but please let me know if you'd like me to make
some changes.

+  const char* const whitelist[] = {
+    "error", "noreturn", "warning"
+  };

Why whitelist noreturn?  I would expect to want that to be consistent.

I expect noreturn to be used on a primary whose definition
is provided but that's not meant to be used the way the API
is otherwise expected to be.  As in:

   template <class T>
   T [[noreturn]] foo () { throw "not implemented"; }

   template <> int foo<int>();   // implemented elsewhere

Marking that template as noreturn seems pointless, and possibly harmful; the deprecated, warning, or error attributes would be better for this situation.

-      /* Merge the type qualifiers.  */
-      if (TREE_READONLY (newdecl))
-       TREE_READONLY (olddecl) = 1;
       if (TREE_THIS_VOLATILE (newdecl))
        TREE_THIS_VOLATILE (olddecl) = 1;
-      if (TREE_NOTHROW (newdecl))
-       TREE_NOTHROW (olddecl) = 1;
+
+      if (merge_attr)
+       {
+         /* Merge the type qualifiers.  */
+         if (TREE_READONLY (newdecl))
+           TREE_READONLY (olddecl) = 1;
+       }
+      else
+       {
+         /* Set the bits that correspond to the const function attributes.  */
+         TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
+       }

Let's limit the const/volatile handling here to non-functions, and handle the const/noreturn attributes for functions in the later hunk along with nothrow/malloc/pure.

-      /* Merge parameter attributes. */
+      /* Merge or assign parameter attributes. */
       tree oldarg, newarg;
- for (oldarg = DECL_ARGUMENTS(olddecl), - newarg = DECL_ARGUMENTS(newdecl);
-           oldarg && newarg;
-           oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg)) {
-          DECL_ATTRIBUTES (newarg)
-              = (*targetm.merge_decl_attributes) (oldarg, newarg);
-          DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
-      }
- + for (oldarg = DECL_ARGUMENTS (olddecl),
+            newarg = DECL_ARGUMENTS (newdecl);
+          oldarg && newarg;
+          oldarg = DECL_CHAIN (oldarg), newarg = DECL_CHAIN (newarg))
+       {
+         DECL_ATTRIBUTES (newarg)
+           = (*targetm.merge_decl_attributes) (oldarg, newarg);
+         DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
+       }
+

I try to avoid reformatting code that I'm not actually changing, to avoid noise in e.g. git blame.

Jason

Reply via email to