Avoid assuming a VLA access specification string contains a closing bracket (PR middl...
authorMartin Sebor <msebor@redhat.com>
Wed, 30 Sep 2020 18:58:09 +0000 (12:58 -0600)
committerMartin Sebor <msebor@redhat.com>
Wed, 30 Sep 2020 18:59:53 +0000 (12:59 -0600)
Resolves:
PR middle-end/97189 - ICE on redeclaration of a function with VLA argument and attribute access

gcc/ChangeLog:

PR middle-end/97189
* attribs.c (attr_access::array_as_string): Avoid assuming a VLA
access specification string contains a closing bracket.

gcc/c-family/ChangeLog:

PR middle-end/97189
* c-attribs.c (append_access_attr): Use the function declaration
location for a warning about an attribute access argument.

gcc/testsuite/ChangeLog:

PR middle-end/97189
* gcc.dg/attr-access-2.c: Adjust caret location.
* gcc.dg/Wvla-parameter-6.c: New test.
* gcc.dg/Wvla-parameter-7.c: New test.

gcc/attribs.c
gcc/c-family/c-attribs.c
gcc/testsuite/gcc.dg/Wvla-parameter-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wvla-parameter-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/attr-access-2.c

index 3f6ec3d3aa39bfdc5ccfb840b07fef487d36fdc0..94b9e02699fbdad4e448c84dad6bcc445c6004c7 100644 (file)
@@ -2270,11 +2270,11 @@ attr_access::array_as_string (tree type) const
             bound is nonconstant and whose access string has "$]" in it)
             extract the bound expression from SIZE.  */
          const char *p = end;
-         for ( ; *p-- != ']'; );
+         for ( ; p != str && *p-- != ']'; );
          if (*p == '$')
            index_type = build_index_type (TREE_VALUE (size));
        }
-      else  if (minsize)
+      else if (minsize)
        index_type = build_index_type (size_int (minsize - 1));
 
       tree arat = NULL_TREE;
index 70b00037d987562934648da5cbd38ee1cf034922..c779d13f02308d85850ceb3bc8545b2e0a33c92a 100644 (file)
@@ -4151,18 +4151,12 @@ append_access_attr (tree node[3], tree attrs, const char *attrstr,
                                 "missing in previous designation",
                                 attrstr);
          else if (newa->internal_p || cura->internal_p)
-           {
-             /* Mismatch in the value of the size argument and a VLA
-                bound.  */
-             location_t argloc = curloc;
-             if (tree arg = get_argument (node[2], newa->sizarg))
-               argloc = DECL_SOURCE_LOCATION (arg);
-             warned = warning_at (argloc, OPT_Wattributes,
-                                  "attribute %qs positional argument 2 "
-                                  "conflicts with previous designation "
-                                  "by argument %u",
-                                  attrstr, cura->sizarg + 1);
-           }
+           /* Mismatch in the value of the size argument and a VLA bound.  */
+           warned = warning_at (curloc, OPT_Wattributes,
+                                "attribute %qs positional argument 2 "
+                                "conflicts with previous designation "
+                                "by argument %u",
+                                attrstr, cura->sizarg + 1);
          else
            /* Mismatch in the value of the size argument between two
               explicit access attributes.  */
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-6.c b/gcc/testsuite/gcc.dg/Wvla-parameter-6.c
new file mode 100644 (file)
index 0000000..268aeec
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
+   and attribute access
+   Also verify the right arguments are underlined in the notes.
+   { dg-do compile }
+   { dg-options "-Wall -fdiagnostics-show-caret" } */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+RW (2, 3) void f1 (int n, int[n], int);
+/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
+   { dg-begin-multiline-output "" }
+ RW (2, 3) void f1 (int n, int[n], int);
+                ^~
+   { dg-end-multiline-output "" }
+   { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-6 }
+   { dg-begin-multiline-output "" }
+ RW (2, 3) void f1 (int n, int[n], int);
+                    ~~~~^  ~~~~~~
+   { dg-end-multiline-output "" } */
+
+
+RW (2)    void f2 (int, int[*], int);
+/* { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
+   { dg-begin-multiline-output "" }
+ RW (2, 3) void f2 (int, int[], int);
+                         ^~~~~
+   { dg-end-multiline-output "" } */
+
+RW (2, 3) void f2 (int, int[], int);
+/* { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
+   { dg-begin-multiline-output "" }
+ RW (2)    void f2 (int, int[*], int);
+                         ^~~~~~
+   { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-7.c b/gcc/testsuite/gcc.dg/Wvla-parameter-7.c
new file mode 100644 (file)
index 0000000..14ce75f
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
+   and attribute access
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+RW (2, 3) void f1 (int n, int[n], int);
+/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
+   { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-2 } */
+
+void call_f1 (int *p)
+{
+  /* Verify that a warning is issued.  Ideally, it seems the VLA bound
+     should take precedence over the attribute and the warning would
+     reference argument 1 but since the conflict in the redeclarations
+     of the function is already diagnosed don't test that (and let it
+     be acceptable for this warning to reference argument 3).  */
+  f1 (-1, p, -1);
+  // { dg-warning "argument \\d value -1 is negative" "warning" { target *-*-* } .-1 }
+}
+
+RW (2)    void f2 (int, int[*], int);
+// { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
+RW (2, 3) void f2 (int, int[], int);
+// { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
+
+void call_f2 (int *p)
+{
+  f2 (-1, p, 0);
+
+  /* Verify that the attribute access on the redeclaration of f2() takes
+     precedence over the one on the first declaration.  */
+  f2 (0, p, -1);
+  // { dg-warning "argument 3 value -1 is negative" "warning" { target *-*-* } .-1 }
+}
index 74762610f98b3b857f9434e14d60315b9b9578d5..76baddffc9f2df3ded5b4ca5a4c7a7a7a8fb6cf1 100644 (file)
@@ -112,5 +112,11 @@ typedef void G1 (int n, int[n], int);
 
 G1 g1;
 
-RW (2, 3) void g1 (int n, int[n], int);     // { dg-warning "24: attribute 'access *\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 3" }
-// { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-1 }
+/* The warning is about the attribute positional argument 2 which refers
+   to the last function argument.  Ideally, the caret would be under
+   the corresponding function argument, i.e., the last one here) but
+   that location isn't available yet.  Verify that the caret doesn't
+   point to function argument 1 which is the VLA bound (that's what
+   the caret in the note points to).  */
+RW (2, 3) void g1 (int n, int[n], int);     // { dg-warning "16: attribute 'access *\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 3" }
+// { dg-message "24:designating the bound of variable length array argument 2" "note" { target *-*-* } .-1 }