* tree.c (handle_abi_tag_attribute): Diagnose invalid arguments.
authorJason Merrill <jason@redhat.com>
Mon, 2 Feb 2015 17:46:56 +0000 (12:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 2 Feb 2015 17:46:56 +0000 (12:46 -0500)
From-SVN: r220356

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/g++.dg/abi/abi-tag13.C [new file with mode: 0644]

index 6cbb3f3730f157c95d5628bce6b0d2bad4a43bec..2e5e2a53d18f4769d43a74addad718c5bc4e8f79 100644 (file)
@@ -1,3 +1,7 @@
+2015-02-02  Jason Merrill  <jason@redhat.com>
+
+       * tree.c (handle_abi_tag_attribute): Diagnose invalid arguments.
+
 2015-01-30  Joseph Myers  <joseph@codesourcery.com>
 
        * class.c, except.c, parser.c, pt.c: All callers of fatal_error
index afb57a3a12a8332144f6c1555411412c09159e4f..c51e42d2a40590b473d2d3f9a5ad59d900e53daa 100644 (file)
@@ -3501,6 +3501,50 @@ static tree
 handle_abi_tag_attribute (tree* node, tree name, tree args,
                          int flags, bool* no_add_attrs)
 {
+  for (tree arg = args; arg; arg = TREE_CHAIN (arg))
+    {
+      tree elt = TREE_VALUE (arg);
+      if (TREE_CODE (elt) != STRING_CST
+         || (!same_type_ignoring_top_level_qualifiers_p
+             (strip_array_types (TREE_TYPE (elt)),
+              char_type_node)))
+       {
+         error ("arguments to the %qE attribute must be narrow string "
+                "literals", name);
+         goto fail;
+       }
+      const char *begin = TREE_STRING_POINTER (elt);
+      const char *end = begin + TREE_STRING_LENGTH (elt);
+      for (const char *p = begin; p != end; ++p)
+       {
+         char c = *p;
+         if (p == begin)
+           {
+             if (!ISALPHA (c) && c != '_')
+               {
+                 error ("arguments to the %qE attribute must contain valid "
+                        "identifiers", name);
+                 inform (input_location, "%<%c%> is not a valid first "
+                         "character for an identifier", c);
+                 goto fail;
+               }
+           }
+         else if (p == end - 1)
+           gcc_assert (c == 0);
+         else
+           {
+             if (!ISALNUM (c) && c != '_')
+               {
+                 error ("arguments to the %qE attribute must contain valid "
+                        "identifiers", name);
+                 inform (input_location, "%<%c%> is not a valid character "
+                         "in an identifier", c);
+                 goto fail;
+               }
+           }
+       }
+    }
+
   if (TYPE_P (*node))
     {
       if (!OVERLOAD_TYPE_P (*node))
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag13.C b/gcc/testsuite/g++.dg/abi/abi-tag13.C
new file mode 100644 (file)
index 0000000..34e8da3
--- /dev/null
@@ -0,0 +1,5 @@
+const char *foo = "bar";
+void __attribute((abi_tag(foo))) f1() {}  // { dg-error "abi_tag" }
+void __attribute((abi_tag(L"foo"))) f2(); // { dg-error "abi_tag" }
+void __attribute((abi_tag("3foo"))) f3(); // { dg-error "abi_tag" }
+void __attribute((abi_tag(1))) f5();     // { dg-error "abi_tag" }