@@ -5436,8 +5436,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
&& (code2 == INTEGER_TYPE || code2 == BITINT_TYPE))
{
if (!null_pointer_constant_p (orig_op2))
- pedwarn (colon_loc, OPT_Wint_conversion,
- "pointer/integer type mismatch in conditional expression");
+ pedpermerror (colon_loc, OPT_Wint_conversion,
+ "pointer/integer type mismatch "
+ "in conditional expression");
else
{
op2 = null_pointer_node;
@@ -5448,8 +5449,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
&& (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
if (!null_pointer_constant_p (orig_op1))
- pedwarn (colon_loc, OPT_Wint_conversion,
- "pointer/integer type mismatch in conditional expression");
+ pedpermerror (colon_loc, OPT_Wint_conversion,
+ "pointer/integer type mismatch "
+ "in conditional expression");
else
{
op1 = null_pointer_node;
@@ -6545,28 +6547,49 @@ error_init (location_t loc, const char *gmsgid, ...)
inform (loc, "(near initialization for %qs)", ofwhat);
}
-/* Issue a pedantic warning for a bad initializer component. OPT is
- the option OPT_* (from options.h) controlling this warning or 0 if
- it is unconditionally given. GMSGID identifies the message. The
- component name is taken from the spelling stack. */
+/* Used to implement pedwarn_init and permerror_init. */
static void ATTRIBUTE_GCC_DIAG (3,0)
-pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
+pedwarn_pedpermerror_init (location_t loc, int opt, const char *gmsgid,
+ va_list *ap, diagnostic_t kind)
{
/* Use the location where a macro was expanded rather than where
it was defined to make sure macros defined in system headers
but used incorrectly elsewhere are diagnosed. */
location_t exploc = expansion_point_location_if_in_system_header (loc);
auto_diagnostic_group d;
- va_list ap;
- va_start (ap, gmsgid);
- bool warned = emit_diagnostic_valist (DK_PEDWARN, exploc, opt, gmsgid, &ap);
- va_end (ap);
+ bool warned = emit_diagnostic_valist (kind, exploc, opt, gmsgid, ap);
char *ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat && warned)
inform (exploc, "(near initialization for %qs)", ofwhat);
}
+/* Issue a pedantic warning for a bad initializer component. OPT is
+ the option OPT_* (from options.h) controlling this warning or 0 if
+ it is unconditionally given. GMSGID identifies the message. The
+ component name is taken from the spelling stack. */
+
+static void ATTRIBUTE_GCC_DIAG (3,0)
+pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
+{
+ va_list ap;
+ va_start (ap, gmsgid);
+ pedwarn_pedpermerror_init (loc, opt, gmsgid, &ap, DK_PEDWARN);
+ va_end (ap);
+}
+
+/* Like pedwarn_init, but issue a permerror. */
+
+static void ATTRIBUTE_GCC_DIAG (3,0)
+pedpermerror_init (location_t loc, int opt, const char *gmsgid, ...)
+{
+ va_list ap;
+ va_start (ap, gmsgid);
+ pedwarn_pedpermerror_init (loc, opt, gmsgid, &ap,
+ flag_pedantic_errors ? DK_PEDWARN : DK_PERMERROR);
+ va_end (ap);
+}
+
/* Issue a warning for a bad initializer component.
OPT is the OPT_W* value corresponding to the warning option that
@@ -7616,27 +7639,28 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
auto_diagnostic_group d;
range_label_for_type_mismatch rhs_label (rhstype, type);
gcc_rich_location richloc (expr_loc, &rhs_label);
- if (pedwarn (&richloc, OPT_Wint_conversion,
- "passing argument %d of %qE makes pointer from "
- "integer without a cast", parmnum, rname))
+ if (pedpermerror (&richloc, OPT_Wint_conversion,
+ "passing argument %d of %qE makes pointer "
+ "from integer without a cast", parmnum, rname))
inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
}
break;
case ic_assign:
- pedwarn (location, OPT_Wint_conversion,
- "assignment to %qT from %qT makes pointer from integer "
- "without a cast", type, rhstype);
+ pedpermerror (location, OPT_Wint_conversion,
+ "assignment to %qT from %qT makes pointer from "
+ "integer without a cast", type, rhstype);
break;
case ic_init:
case ic_init_const:
- pedwarn_init (location, OPT_Wint_conversion,
- "initialization of %qT from %qT makes pointer from "
- "integer without a cast", type, rhstype);
+ pedpermerror_init (location, OPT_Wint_conversion,
+ "initialization of %qT from %qT makes pointer "
+ "from integer without a cast", type, rhstype);
break;
case ic_return:
- pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
- "function with return type %qT makes pointer from "
- "integer without a cast", rhstype, type);
+ pedpermerror_init (location, OPT_Wint_conversion,
+ "returning %qT from a function with return type "
+ "%qT makes pointer from integer without a cast",
+ rhstype, type);
break;
default:
gcc_unreachable ();
@@ -7654,27 +7678,27 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
auto_diagnostic_group d;
range_label_for_type_mismatch rhs_label (rhstype, type);
gcc_rich_location richloc (expr_loc, &rhs_label);
- if (pedwarn (&richloc, OPT_Wint_conversion,
- "passing argument %d of %qE makes integer from "
- "pointer without a cast", parmnum, rname))
+ if (pedpermerror (&richloc, OPT_Wint_conversion,
+ "passing argument %d of %qE makes integer from "
+ "pointer without a cast", parmnum, rname))
inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
}
break;
case ic_assign:
- pedwarn (location, OPT_Wint_conversion,
- "assignment to %qT from %qT makes integer from pointer "
- "without a cast", type, rhstype);
+ pedpermerror (location, OPT_Wint_conversion,
+ "assignment to %qT from %qT makes integer from "
+ "pointer without a cast", type, rhstype);
break;
case ic_init:
case ic_init_const:
- pedwarn_init (location, OPT_Wint_conversion,
- "initialization of %qT from %qT makes integer from "
- "pointer without a cast", type, rhstype);
+ pedpermerror_init (location, OPT_Wint_conversion,
+ "initialization of %qT from %qT makes integer "
+ "from pointer without a cast", type, rhstype);
break;
case ic_return:
- pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
- "function with return type %qT makes integer from "
- "pointer without a cast", rhstype, type);
+ pedpermerror (location, OPT_Wint_conversion, "returning %qT from a "
+ "function with return type %qT makes integer from "
+ "pointer without a cast", rhstype, type);
break;
default:
gcc_unreachable ();
@@ -6179,6 +6179,7 @@ only by this flag, but it also downgrades some C and C++ diagnostics
that have their own flag:
@gccoptlist{
+-Wint-conversion @r{(C)}
-Wnarrowing @r{(C++)}
}
@@ -8545,6 +8546,11 @@ conversions. This warning is about implicit conversions; for explicit
conversions the warnings @option{-Wno-int-to-pointer-cast} and
@option{-Wno-pointer-to-int-cast} may be used.
+By default, in C99 and later dialects of C, GCC treats this issue as an
+error. The error can be downgraded to a warning using
+@option{-fpermissive} (along with certain other errors), or for this
+error alone, with @option{-Wno-error=int-conversion}.
+
This warning is upgraded to an error by @option{-pedantic-errors}.
@opindex Wzero-length-bounds
@@ -4,11 +4,11 @@
int
foo (int a)
{
- return __atomic_is_lock_free (2, a); /* { dg-warning "pointer from integer" "" { target c } } */
+ return __atomic_is_lock_free (2, a); /* { dg-error "pointer from integer" "" { target c } } */
} /* { dg-error "invalid conversion" "" { target c++ } .-1 } */
int
bar (int a)
{
- return __atomic_always_lock_free (2, a); /* { dg-warning "pointer from integer" "" { target c } } */
+ return __atomic_always_lock_free (2, a); /* { dg-error "pointer from integer" "" { target c } } */
} /* { dg-error "invalid conversion" "" { target c++ } .-1 } */
@@ -1,7 +1,7 @@
/* PR middle-end/86202 - ICE in get_range_info calling an invalid memcpy()
declaration */
/* { dg-do compile } */
-/* { dg-options "-Wint-conversion" } */
+/* { dg-options "-fpermissive -Wint-conversion" } */
void *memcpy (void *, void *, __SIZE_TYPE__ *); /* { dg-warning "conflicting types for built-in function .memcpy." } */
void *a, *b;
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
const char *
f1 (int flag)
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+const char *
+f1 (int flag)
+{
+ return flag ? "" : 1; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+}
+
+const char *
+f2 (int flag)
+{
+ return flag ? 1 : ""; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+}
@@ -1,7 +1,7 @@
/* Test diagnostics for bad implicit type conversions. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
-/* { dg-options "-pedantic -ftrack-macro-expansion=0" } */
+/* { dg-options "-pedantic -fpermissive -ftrack-macro-expansion=0" } */
#define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy
#define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy
new file mode 100644
@@ -0,0 +1,21 @@
+/* Test diagnostics for bad implicit type conversions. Error variant. */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=0" } */
+
+#define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy
+#define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy
+#define TESTASS(ID, TL, TR) void ID##F(TR x) { TL y; y = x; } extern int dummy
+#define TESTINI(ID, TL, TR) void ID##F(TR x) { TL y = x; } extern int dummy
+#define TESTRET(ID, TL, TR) TR ID##V; TL ID##F(void) { return ID##V; } extern int dummy
+
+TESTARG(ciia, char *, int); /* { dg-error "passing argument 1 of 'ciiaF' makes pointer from integer without a cast" } */
+TESTARP(ciib, char *, int); /* { dg-error "passing argument 1 of 'ciibFp.x' makes pointer from integer without a cast" } */
+TESTASS(ciic, char *, int); /* { dg-error "assignment to 'char \\*' from 'int' makes pointer from integer without a cast" } */
+TESTINI(ciid, char *, int); /* { dg-error "initialization of 'char \\*' from 'int' makes pointer from integer without a cast" } */
+TESTRET(ciie, char *, int); /* { dg-error "returning 'int' from a function with return type 'char \\*' makes pointer from integer without a cast" } */
+
+TESTARG(iica, int, char *); /* { dg-error "passing argument 1 of 'iicaF' makes integer from pointer without a cast" } */
+TESTARP(iicb, int, char *); /* { dg-error "passing argument 1 of 'iicbFp.x' makes integer from pointer without a cast" } */
+TESTASS(iicc, int, char *); /* { dg-error "assignment to 'int' from 'char \\*' makes integer from pointer without a cast" } */
+TESTINI(iicd, int, char *); /* { dg-error "initialization of 'int' from 'char \\*' makes integer from pointer without a cast" } */
+TESTRET(iice, int, char *); /* { dg-error "returning 'char \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
@@ -1,6 +1,6 @@
/* PR c/81233 */
/* { dg-do compile } */
-/* { dg-options "-Wc++-compat -Wpedantic" } */
+/* { dg-options "-fpermissive -Wc++-compat -Wpedantic" } */
/* Test we're printing the types, like the good compiler we are. */
enum E1 { A } e;
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-Wpedantic" } */
+/* Test we're printing the types, like the good compiler we are. */
+
+extern void foo2 (int *); /* { dg-message "expected 'int \\*' but argument is of type 'int'" } */
+extern void foo3 (int); /* { dg-message "expected 'int' but argument is of type 'int \\*'" } */
+
+int *
+fn1 (int *p)
+{
+ p = 1; /* { dg-error "assignment to 'int \\*' from 'int' makes pointer from integer without a cast" } */
+ int *q = 1; /* { dg-error "initialization of 'int \\*' from 'int' makes pointer from integer without a cast" } */
+ foo2 (1); /* { dg-error "passing argument 1 of 'foo2' makes pointer from integer without a cast" } */
+ return 1; /* { dg-error "returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
+
+int
+fn2 (int i, int *p)
+{
+ i = p; /* { dg-error "assignment to 'int' from 'int \\*' makes integer from pointer without a cast" } */
+ int j = p; /* { dg-error "initialization of 'int' from 'int \\*' makes integer from pointer without a cast" } */
+ foo3 (p); /* { dg-error "passing argument 1 of 'foo3' makes integer from pointer without a cast" } */
+ return p; /* { dg-error "returning 'int \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
+}
new file mode 100644
@@ -0,0 +1,18 @@
+/* PR c/35738 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void foo (void);
+
+void
+bar (void *p)
+{
+ int i = 0;
+ char q[10];
+#pragma omp atomic
+ i += q; /* { dg-error "makes integer from pointer without a cast" } */
+#pragma omp atomic
+ i += foo; /* { dg-error "makes integer from pointer without a cast" } */
+#pragma omp atomic
+ i += p; /* { dg-error "makes integer from pointer without a cast" } */
+}
@@ -1,6 +1,6 @@
/* PR c/35738 */
/* { dg-do compile } */
-/* { dg-options "-fopenmp" } */
+/* { dg-options "-fpermissive -fopenmp" } */
void foo (void);
@@ -7,9 +7,9 @@
char s0[] = {"abc",1}; /* { dg-error "'char..' initializer|near init" } */
char s1[] = {"abc","a"}; /* { dg-error "'char..' initializer|near init" } */
char s2[] = {1,"abc"}; /* { dg-error "'char..' initializer|near init|computable at load time" } */
-/* { dg-warning "integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-error "integer from pointer without a cast" "" { target *-*-* } .-1 } */
char s3[5] = {"abc",1}; /* { dg-error "'char.5.' initializer|near init" } */
char s4[5] = {"abc","a"}; /* { dg-error "'char.5.' initializer|near init" } */
char s5[5] = {1,"abc"}; /* { dg-error "'char.5.' initializer|near init|computable at load time" } */
-/* { dg-warning "integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-error "integer from pointer without a cast" "" { target *-*-* } .-1 } */
@@ -47,10 +47,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "25:integer overflow in expression"
constants. The third has the overflow in an unevaluated
subexpression, so is a null pointer constant. */
void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */
void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
void *r = (1 ? 0 : INT_MAX+1);
void
@@ -53,10 +53,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" }
subexpression, so is a null pointer constant. */
void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
void *r = (1 ? 0 : INT_MAX+1);
void
new file mode 100644
@@ -0,0 +1,187 @@
+/* { dg-options "-fdiagnostics-show-caret -Wpointer-sign" } */
+
+/* A collection of calls where argument 2 is of the wrong type.
+ Like param-type-mismatch.c, but expecting errors. */
+
+/* decl, with argname. */
+
+extern int callee_1 (int one, const char *two, float three); /* { dg-line callee_1 } */
+
+int test_1 (int first, int second, float third)
+{
+ return callee_1 (first, second, third); /* { dg-error "passing argument 2 of 'callee_1' makes pointer from integer without a cast" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_1 (first, second, third);
+ ^~~~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_1 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_1 (int one, const char *two, float three);
+ ~~~~~~~~~~~~^~~
+ { dg-end-multiline-output "" } */
+}
+
+/* decl, without argname. */
+
+extern int callee_2 (int, const char *, float); /* { dg-line callee_2 } */
+
+int test_2 (int first, int second, float third)
+{
+ return callee_2 (first, second, third); /* { dg-error "passing argument 2 of 'callee_2' makes pointer from integer without a cast" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_2 (first, second, third);
+ ^~~~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_2 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_2 (int, const char *, float);
+ ^~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+}
+
+/* defn, with argname. */
+
+static int callee_3 (int one, const char *two, float three) /* { dg-line callee_3 } */
+{
+ return callee_2 (one, two, three);
+}
+
+int test_3 (int first, int second, float third)
+{
+ return callee_3 (first, second, third); // { dg-error "passing argument 2 of 'callee_3' makes pointer from integer without a cast" }
+ /* { dg-begin-multiline-output "" }
+ return callee_3 (first, second, third);
+ ^~~~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_3 } */
+ /* { dg-begin-multiline-output "" }
+ static int callee_3 (int one, const char *two, float three)
+ ~~~~~~~~~~~~^~~
+ { dg-end-multiline-output "" } */
+}
+
+/* Trivial decl, with argname. */
+
+extern int callee_4 (int one, float two, float three); /* { dg-line callee_4 } */
+
+int test_4 (int first, const char *second, float third)
+{
+ return callee_4 (first, second, third); /* { dg-error "incompatible type for argument 2 of 'callee_4'" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_4 (first, second, third);
+ ^~~~~~
+ |
+ const char *
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'float' but argument is of type 'const char \\*'" "" { target *-*-* } callee_4 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_4 (int one, float two, float three);
+ ~~~~~~^~~
+ { dg-end-multiline-output "" } */
+}
+
+/* Trivial decl, without argname. */
+
+extern int callee_5 (int, float, float); /* { dg-line callee_5 } */
+
+int test_5 (int first, const char *second, float third)
+{
+ return callee_5 (first, second, third); /* { dg-error "incompatible type for argument 2 of 'callee_5'" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_5 (first, second, third);
+ ^~~~~~
+ |
+ const char *
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'float' but argument is of type 'const char \\*'" "" { target *-*-* } callee_5 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_5 (int, float, float);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+}
+
+/* Callback with name. */
+
+extern int callee_6 (int one, int (*two)(int, int), float three); /* { dg-line callee_6 } */
+
+int test_6 (int first, int second, float third)
+{
+ return callee_6 (first, second, third); /* { dg-error "passing argument 2 of 'callee_6' makes pointer from integer without a cast" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_6 (first, second, third);
+ ^~~~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-message " expected 'int \\(\\*\\)\\(int, int\\)' but argument is of type 'int'" "" { target *-*-* } callee_6 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_6 (int one, int (*two)(int, int), float three);
+ ~~~~~~^~~~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+}
+
+/* Callback without name. */
+
+extern int callee_7 (int one, int (*)(int, int), float three); /* { dg-line callee_7 } */
+
+int test_7 (int first, int second, float third)
+{
+ return callee_7 (first, second, third); /* { dg-error "passing argument 2 of 'callee_7' makes pointer from integer without a cast" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_7 (first, second, third);
+ ^~~~~~
+ |
+ int
+ { dg-end-multiline-output "" } */
+ /* { dg-message " expected 'int \\(\\*\\)\\(int, int\\)' but argument is of type 'int'" "" { target *-*-* } callee_7 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_7 (int one, int (*)(int, int), float three);
+ ^~~~~~~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+}
+
+/* -Wincompatible-pointer-types for a parameter. */
+
+extern int callee_8 (int one, float *two, float (three)); /* { dg-line callee_8 } */
+
+int test_8 (int first, int *second, float third)
+{
+ return callee_8 (first, second, third); /* { dg-warning "passing argument 2 of 'callee_8' from incompatible pointer type" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_8 (first, second, third);
+ ^~~~~~
+ |
+ int *
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'float \\*' but argument is of type 'int \\*'" "" { target *-*-* } callee_8 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_8 (int one, float *two, float (three));
+ ~~~~~~~^~~
+ { dg-end-multiline-output "" } */
+}
+
+/* -Wpointer-sign for a parameter. */
+
+extern int callee_9 (int one, int *two, float (three)); /* { dg-line callee_9 } */
+
+int test_9 (int first, unsigned int *second, float third)
+{
+ return callee_9 (first, second, third); /* { dg-warning "pointer targets in passing argument 2 of 'callee_9' differ in signedness" } */
+ /* { dg-begin-multiline-output "" }
+ return callee_9 (first, second, third);
+ ^~~~~~
+ |
+ unsigned int *
+ { dg-end-multiline-output "" } */
+ /* { dg-message "expected 'int \\*' but argument is of type 'unsigned int \\*'" "" { target *-*-* } callee_9 } */
+ /* { dg-begin-multiline-output "" }
+ extern int callee_9 (int one, int *two, float (three));
+ ~~~~~^~~
+ { dg-end-multiline-output "" } */
+}
@@ -1,4 +1,4 @@
-/* { dg-options "-fdiagnostics-show-caret -Wpointer-sign" } */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret -Wpointer-sign" } */
/* A collection of calls where argument 2 is of the wrong type. */
@@ -1,6 +1,6 @@
/* PR c/61162 */
/* { dg-do compile } */
-/* { dg-options "-Wc++-compat -Wpointer-sign -Wpedantic" } */
+/* { dg-options "-fpermissive -Wc++-compat -Wpointer-sign -Wpedantic" } */
enum e { A };
struct s { int a; };
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int
+fn4 (int *a)
+{
+ return a; /* { dg-error "10:returning 'int \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
+}
+
+int *
+fn5 (int a)
+{
+ return a; /* { dg-error "10:returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-Wpedantic" } */
+/* { dg-options "-fpermissive -Wpedantic" } */
/* __builtin_speculation_safe_value returns a value with the same type
as its first argument. There should be a warning if that isn't
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wpedantic" } */
+
+/* __builtin_speculation_safe_value returns a value with the same type
+ as its first argument. There should be an error if that isn't
+ type-compatible with the use. */
+int *
+f (int x)
+{
+ return __builtin_speculation_safe_value (x); /* { dg-error "returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
+
+/* { dg-prune-output "this target does not define a speculation barrier;" } */
@@ -2,7 +2,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target lp64 } */
-/* { dg-options "-O3 -march=armv8.5-a+memtag" } */
+/* { dg-options "-fpermissive -O3 -march=armv8.5-a+memtag" } */
#include "arm_acle.h"
@@ -67,4 +67,4 @@ test_memtag_error_argument (void)
__arm_mte_ptrdiff(no_decl2, 0); /* { dg-error {} } */
__arm_mte_ptrdiff(0); /* { dg-error {} } */
__arm_mte_ptrdiff(); /* { dg-error {} } */
-}
\ No newline at end of file
+}
new file mode 100644
@@ -0,0 +1,71 @@
+/* Test the MEMTAG intrinsic qualifier warnings and argument errors. */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O3 -march=armv8.5-a+memtag" } */
+
+#include "arm_acle.h"
+
+void
+test_memtag_warning_return_qualifier (void)
+{
+ const char *c;
+ volatile char *v;
+ char *n;
+ int *i;
+ int64_t d;
+
+ v = __arm_mte_get_tag(c); /* { dg-warning {assignment} } */
+ n = __arm_mte_get_tag(c); /* { dg-warning {assignment} } */
+ i = __arm_mte_get_tag(c); /* { dg-warning {assignment} } */
+ c = __arm_mte_get_tag(v); /* { dg-warning {assignment} } */
+ n = __arm_mte_get_tag(v); /* { dg-warning {assignment} } */
+
+ i = __arm_mte_create_random_tag (c, 0); /* { dg-warning {assignment} } */
+ i = __arm_mte_increment_tag (c, 0); /* { dg-warning {assignment} } */
+
+ c = __arm_mte_get_tag(n); /* No warning. */
+ d = __arm_mte_ptrdiff(c, i); /* No warning. */
+}
+
+void
+test_memtag_warning_argument (void)
+{
+ const char *c;
+ __arm_mte_exclude_tag(0, 0); /* No warning. */
+ __arm_mte_create_random_tag (0, 0); /* No warning. */
+ __arm_mte_set_tag(0); /* No warning. */
+ __arm_mte_get_tag(0); /* No warning. */
+ __arm_mte_increment_tag (0, 15); /* No warning. */
+ __arm_mte_ptrdiff(c, 0); /* No warning. */
+ __arm_mte_ptrdiff(0, c); /* No warning. */
+}
+
+void
+test_memtag_error_argument (void)
+{
+ /* Produce errors properly for invalid arguments. */
+ __arm_mte_exclude_tag(no_decl, 0); /* { dg-error {} } */
+ __arm_mte_exclude_tag(); /* { dg-error {} } */
+ __arm_mte_ptrdiff(no_decl2, 0); /* { dg-error {} } */
+ __arm_mte_ptrdiff(0); /* { dg-error {} } */
+ __arm_mte_ptrdiff(); /* { dg-error {} } */
+
+ const char *c;
+ uint64_t i;
+ __arm_mte_exclude_tag(i, 0); /* { dg-error {argument} } */
+ __arm_mte_create_random_tag (i, 0); /* { dg-error {argument} } */
+ __arm_mte_set_tag(i); /* { dg-error {argument} } */
+ __arm_mte_get_tag(i); /* { dg-error {argument} } */
+ __arm_mte_increment_tag (i, 15); /* { dg-error {argument} } */
+ __arm_mte_ptrdiff(c, i); /* { dg-error {argument} } */
+ __arm_mte_ptrdiff(i, c); /* { dg-error {argument} } */
+
+ __arm_mte_exclude_tag(1, 0); /* { dg-error {argument} } */
+ __arm_mte_create_random_tag (1, 0); /* { dg-error {argument} } */
+ __arm_mte_set_tag(1); /* { dg-error {argument} } */
+ __arm_mte_get_tag(1); /* { dg-error {argument} } */
+ __arm_mte_increment_tag (1, 15); /* { dg-error {argument} } */
+ __arm_mte_ptrdiff(c, 1); /* { dg-error {argument} } */
+ __arm_mte_ptrdiff(1, c); /* { dg-error {argument} } */
+}
@@ -13,6 +13,6 @@ f1 (svbool_t pg, signed char *s8_ptr, svint8_t s8)
svld1_vnum (pg, s8_ptr, 0, 0); /* { dg-error {too many arguments to function 'svld1_vnum'} } */
svld1_vnum (0, s8_ptr, 0); /* { dg-error {passing 'int' to argument 1 of 'svld1_vnum', which expects 'svbool_t'} } */
svld1_vnum (pg, 0, 0); /* { dg-error {passing 'int' to argument 2 of 'svld1_vnum', which expects a pointer type} } */
- svld1_vnum (pg, s8_ptr, s8_ptr); /* { dg-warning "passing argument 3 of 'svld1_vnum_s8' makes integer from pointer without a cast" } */
+ svld1_vnum (pg, s8_ptr, s8_ptr); /* { dg-error "passing argument 3 of 'svld1_vnum_s8' makes integer from pointer without a cast" } */
svld1_vnum (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1_vnum', which expects 'int64_t'} } */
}
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, void *void_ptr, struct s *s_ptr,
svst1_vnum (0, s8_ptr, 0, s8); /* { dg-error {passing 'int' to argument 1 of 'svst1_vnum', which expects 'svbool_t'} } */
svst1_vnum (pg, s8_ptr, pg, s8); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_vnum', which expects 'int64_t'} } */
svst1_vnum (pg, s8_ptr, s8, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svst1_vnum', which expects 'int64_t'} } */
- svst1_vnum (pg, s8_ptr, void_ptr, s8); /* { dg-warning "passing argument 3 of 'svst1_vnum_s8' makes integer from pointer without a cast" } */
+ svst1_vnum (pg, s8_ptr, void_ptr, s8); /* { dg-error "passing argument 3 of 'svst1_vnum_s8' makes integer from pointer without a cast" } */
svst1_vnum (pg, void_ptr, 0, 0); /* { dg-error {passing 'int' to argument 4 of 'svst1_vnum', which expects an SVE vector type} } */
svst1_vnum (pg, void_ptr, 0, pg); /* { dg-error {'svst1_vnum' has no form that takes 'svbool_t' arguments} } */
svst1_vnum (pg, 0, 0, s8);
@@ -26,7 +26,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
svst1_scatter_index (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32index_f32' from incompatible pointer type" } */
svst1_scatter_index (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_index', which expects a vector or pointer base address} } */
- svst1_scatter_index (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svst1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
+ svst1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
svst1_scatter_index (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_scatter_index', which expects 'int64_t'} } */
svst1_scatter_index (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svst1_scatter_index', which expects 'int64_t'} } */
@@ -28,7 +28,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
svstnt1_scatter_index (pg, cf64_ptr, s64, f64); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_s64index_f64' from incompatible pointer type" } */
svstnt1_scatter_index (pg, s, s64, s64); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_index', which expects a vector or pointer base address} } */
- svstnt1_scatter_index (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svstnt1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
+ svstnt1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
svstnt1_scatter_index (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svstnt1_scatter_index', which expects 'int64_t'} } */
svstnt1_scatter_index (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svstnt1_scatter_index', which expects 'int64_t'} } */
@@ -26,7 +26,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
svst1_scatter_offset (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32offset_f32' from incompatible pointer type" } */
svst1_scatter_offset (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_offset', which expects a vector or pointer base address} } */
- svst1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svst1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
+ svst1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
svst1_scatter_offset (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_scatter_offset', which expects 'int64_t'} } */
svst1_scatter_offset (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svst1_scatter_offset', which expects 'int64_t'} } */
@@ -28,7 +28,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
svstnt1_scatter_offset (pg, cf32_ptr, u32, f32); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_u32offset_f32' from incompatible pointer type" } */
svstnt1_scatter_offset (pg, s, u32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_offset', which expects a vector or pointer base address} } */
- svstnt1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svstnt1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
+ svstnt1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
svstnt1_scatter_offset (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svstnt1_scatter_offset', which expects 'int64_t'} } */
svstnt1_scatter_offset (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svstnt1_scatter_offset', which expects 'int64_t'} } */