Hi!

As the testcase shows, we are silently accepting writes into const
variables, because the type generic builtins don't have a prototype.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2019-05-27  Jakub Jelinek  <ja...@redhat.com>

        PR c/90628
        * c-common.c (check_builtin_function_arguments)
        <case BUILTIN_*_OVERFLOW>: Diagnose pointer to const qualified integer
        as last argument.

        * c-c++-common/builtin-arith-overflow-3.c: New test.

--- gcc/c-family/c-common.c.jj  2019-05-21 16:16:48.068973678 +0200
+++ gcc/c-family/c-common.c     2019-05-27 10:46:25.525968739 +0200
@@ -5995,6 +5995,13 @@ check_builtin_function_arguments (locati
                        "has pointer to boolean type", fndecl);
              return false;
            }
+         else if (TYPE_READONLY (TREE_TYPE (TREE_TYPE (args[2]))))
+           {
+             error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
+                       "has pointer type to %<const%> qualified integer",
+                       fndecl);
+             return false;
+           }
          return true;
        }
       return false;
--- gcc/testsuite/c-c++-common/builtin-arith-overflow-3.c.jj    2019-05-27 
10:51:46.829710217 +0200
+++ gcc/testsuite/c-c++-common/builtin-arith-overflow-3.c       2019-05-27 
10:53:10.972330933 +0200
@@ -0,0 +1,42 @@
+/* PR c/90628 */
+/* { dg-do compile } */
+
+const int a = 1, b = 2, c = 3;
+const long d = 4, e = 5, f = 6;
+const long long g = 7, h = 8, i = 9;
+
+void
+f1 ()
+{
+  __builtin_add_overflow (a, b, &c);   /* { dg-error "argument 3 in call to 
function '__builtin_add_overflow' has pointer type to 'const' qualified 
integer" } */
+}
+
+void
+f2 ()
+{
+  __builtin_sub_overflow (d, e, &f);   /* { dg-error "argument 3 in call to 
function '__builtin_sub_overflow' has pointer type to 'const' qualified 
integer" } */
+}
+
+void
+f3 ()
+{
+  __builtin_mul_overflow (g, h, &i);   /* { dg-error "argument 3 in call to 
function '__builtin_mul_overflow' has pointer type to 'const' qualified 
integer" } */
+}
+
+void
+f4 ()
+{
+  __builtin_sadd_overflow (a, b, &c);  /* { dg-warning "passing argument 3 of 
'__builtin_sadd_overflow' discards 'const' qualifier from pointer target type" 
"" { target c } } */
+}      /* { dg-error "invalid conversion from 'const int\\*' to 'int\\*'" "" { 
target c++ } .-1 } */
+
+void
+f5 ()
+{
+  __builtin_ssubl_overflow (d, e, &f); /* { dg-warning "passing argument 3 of 
'__builtin_ssubl_overflow' discards 'const' qualifier from pointer target type" 
"" { target c } } */
+}      /* { dg-error "invalid conversion from 'const long int\\*' to 'long 
int\\*'" "" { target c++ } .-1 } */
+
+void
+f6 ()
+{
+  __builtin_smulll_overflow (g, h, &i);        /* { dg-warning "passing 
argument 3 of '__builtin_smulll_overflow' discards 'const' qualifier from 
pointer target type" "" { target c } } */
+}      /* { dg-error "invalid conversion from 'const long long int\\*' to 
'long long int\\*'" "" { target c++ } .-1 } */

        Jakub

Reply via email to