diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 18:13:43 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-29 18:13:43 +0000 |
commit | a75b1c712f1eaddc69919461ead67f4ac21663fe (patch) | |
tree | a06c7550ad4d8d100141b10b1c0d61bf7548b888 /gcc/testsuite/gcc.dg | |
parent | 088cc5d52e3bab879a7b3aa48b3de9127e948bb0 (diff) | |
download | gcc-a75b1c712f1eaddc69919461ead67f4ac21663fe.tar.gz |
PR c/456
PR c/5675
PR c/19976
PR c/29116
PR c/31871
PR c/35198
fixincludes:
* inclhack.def (glibc_tgmath): New fix.
* fixincl.x: Regenerate.
* tests/base/tgmath.h: New.
gcc:
* builtins.c (fold_builtin_sincos): Build COMPOUND_EXPR in
void_type_node.
(fold_call_expr): Return a NOP_EXPR from folding rather than the
contained expression.
* c-common.c (c_fully_fold, c_fully_fold_internal, c_save_expr):
New.
(c_common_truthvalue_conversion): Use c_save_expr. Do not fold
conditional expressions for C.
(decl_constant_value_for_optimization): Move from
decl_constant_value_for_broken_optimization in c-typeck.c. Check
whether optimizing and that the expression is a VAR_DECL not of
array type instead of doing such checks in the caller. Do not
check pedantic. Call gcc_unreachable for C++.
* c-common.def (C_MAYBE_CONST_EXPR): New.
* c-common.h (c_fully_fold, c_save_expr,
decl_constant_value_for_optimization): New prototypes.
(C_MAYBE_CONST_EXPR_PRE, C_MAYBE_CONST_EXPR_EXPR,
C_MAYBE_CONST_EXPR_INT_OPERANDS, C_MAYBE_CONST_EXPR_NON_CONST,
EXPR_INT_CONST_OPERANDS): Define.
* c-convert.c (convert): Strip nops from expression.
* c-decl.c (groktypename): Take extra parameters expr and
expr_const_operands. Update call to grokdeclarator.
(start_decl): Update call to grokdeclarator. Add statement for
expressions used in type of decl.
(grokparm): Update call to grokdeclarator.
(push_parm_decl): Update call to grokdeclarator.
(build_compound_literal): Add parameter non_const and build a
C_MAYBE_COSNT_EXPR if applicable.
(grokdeclarator): Take extra parameters expr and
expr_const_operands. Track expressions used in declaration
specifiers and declarators. Fold array sizes and track whether
they are constant expressions and whether they are integer
constant expressions.
(parser_xref_tag): Set expr and expr_const_operands fields in
return value.
(grokfield): Update call to grokdeclarator.
(start_function): Update call to grokdeclarator.
(build_null_declspecs): Set expr and expr_const_operands fields in
return value.
(declspecs_add_type): Handle expressions in typeof specifiers.
* c-parser.c (c_parser_declspecs): Set expr and
expr_const_operands fields for declaration specifiers.
(c_parser_enum_specifier): Likewise.
(c_parser_struct_or_union_specifier): Likewise.
(c_parser_typeof_specifier): Likewise. Update call to
groktypename. Fold expression as needed. Return expressions with
type instead of adding statements.
(c_parser_attributes): Update calls to c_parser_expr_list.
(c_parser_statement_after_labels): Fold expression before passing
to objc_build_throw_stmt.
(c_parser_condition): Fold expression.
(c_parser_asm_operands): Fold expression.
(c_parser_conditional_expression): Use c_save_expr. Update call
to build_conditional_expr.
(c_parser_alignof_expression): Update call to groktypename.
(c_parser_postfix_expression): Preserve C_MAYBE_CONST_EXPR as
original_code. Fold expression argument of va_arg. Create
C_MAYBE_CONST_EXPR to preserve side effects of expressions in type
argument to va_arg. Update calls to groktypename. Fold array
index for offsetof. Verify that first argument to
__builtin_choose_expr has integer type.
(c_parser_postfix_expression_after_paren_type): Update calls to
groktypename and build_compound_literal. Handle expressions with
side effects in type name.
(c_parser_postfix_expression_after_primary): Update call to
c_parser_expr_list. Set original_code for calls to
__builtin_constant_p.
(c_parser_expr_list): Take extra parameter fold_p. Fold
expressions if requested.
(c_parser_objc_type_name): Update call to groktypename.
(c_parser_objc_synchronized_statement): Fold expression.
(c_parser_objc_receiver): Fold expression.
(c_parser_objc_keywordexpr): Update call to c_parser_expr_list.
(c_parser_omp_clause_num_threads, c_parser_omp_clause_schedule,
c_parser_omp_atomic, c_parser_omp_for_loop): Fold expressions.
* c-tree.h (CONSTRUCTOR_NON_CONST): Define.
(struct c_typespec): Add elements expr and expr_const_operands.
(struct c_declspecs): Add elements expr and expr_const_operands.
(groktypename, build_conditional_expr, build_compound_literal):
Update prototypes.
(in_late_binary_op): Declare.
* c-typeck.c (note_integer_operands): New function.
(in_late_binary_op): New variable.
(decl_constant_value_for_broken_optimization): Move to c-common.c
and rename to decl_constant_value_for_optimization.
(default_function_array_conversion): Do not strip nops.
(default_conversion): Do not call
decl_constant_value_for_broken_optimization.
(build_array_ref): Do not fold result.
(c_expr_sizeof_expr): Fold operand. Use C_MAYBE_CONST_EXPR for
result when operand is a VLA.
(c_expr_sizeof_type): Update call to groktypename. Handle
expressions included in type name. Use C_MAYBE_CONST_EXPR for
result when operand names a VLA type.
(build_function_call): Update call to build_compound_literal.
Only fold result for calls to __builtin_* functions. Strip
NOP_EXPR from INTEGER_CST returned from such functions. Fold
the function designator.
(convert_arguments): Fold arguments. Update call to
convert_for_assignment.
(build_unary_op): Handle increment and decrement of
C_MAYBE_CONST_EXPR. Move lvalue checks for increment and
decrement earlier. Fold operand of increment and decrement.
Handle address of C_MAYBE_CONST_EXPR. Only fold expression being
built for integer operand. Wrap returns that are INTEGER_CSTs
without being integer constant expressions or that have integer
constant operands without being INTEGER_CSTs.
(lvalue_p): Handle C_MAYBE_CONST_EXPR.
(build_conditional_expr): Add operand ifexp_bcp. Track whether
result is an integer constant expression or can be used in
unevaluated parts of one and avoid folding and wrap as
appropriate. Fold operands before possibly doing -Wsign-compare
warnings.
(build_compound_expr): Wrap result for C99 if operands can be used
in integer constant expressions.
(build_c_cast): Update call to digest_init. Do not ignore
overflow from casting floating-point constants to integers. Wrap
results that could be confused with integer constant expressions,
null pointer constants or floating-point constants.
(c_cast_expr): Update call to groktypename. Handle expressions
included in type name.
(build_modify_expr): Handle modifying a C_MAYBE_CONST_EXPR. Fold
lhs inside possible SAVE_EXPR. Fold RHS before assignment.
Update calls to convert_for_assignment.
(convert_for_assignment): Take new parameter
null_pointer_constant. Do not strip nops or call
decl_constant_value_for_broken_optimization. Set
in_late_binary_op for conversions to boolean.
(store_init_value): Update call to digest_init.
(digest_init): Take new parameter null_pointer_constant. Do not
call decl_constant_value_for_broken_optimization. pedwarn for
initializers not constant expressions. Update calls to
convert_for_assignment.
(constructor_nonconst): New.
(struct constructor_stack): Add nonconst element.
(really_start_incremental_init, push_init_level, pop_init_level):
Handle constructor_nonconst and nonconst element.
(set_init_index): Call constant_expression_warning for array
designators.
(output_init_element): Fold value. Set constructor_nonconst as
applicable. pedwarn for initializers not constant expressions.
Update call to digest_init. Call constant_expression_warning
where constant initializers are required.
(process_init_element): Use c_save_expr.
(c_finish_goto_ptr): Fold expression.
(c_finish_return): Fold return value. Update call to
convert_for_assignment.
(c_start_case): Fold switch expression.
(c_process_expr_stmt): Fold expression.
(c_finish_stmt_expr): Create C_MAYBE_CONST_EXPR as needed to
ensure statement expression is not evaluated in constant
expression.
(build_binary_op): Track whether results are integer constant
expressions or may occur in such, disable folding and wrap results
as applicable. Fold operands for -Wsign-compare warnings unless
in_late_binary_op.
(c_objc_common_truthvalue_conversion): Handle results folded to
integer constants that are not integer constant expressions.
* doc/extend.texi: Document when typeof operands are evaluated,
that condition of __builtin_choose_expr is an integer constant
expression, and more about use of __builtin_constant_p in
initializers.
gcc/objc:
* objc-act.c (objc_finish_try_stmt): Set in_late_binary_op.
gcc/testsuite:
* gcc.c-torture/compile/20081108-1.c,
gcc.c-torture/compile/20081108-2.c,
gcc.c-torture/compile/20081108-3.c, gcc.dg/bconstp-2.c,
gcc.dg/bconstp-3.c, gcc.dg/bconstp-4.c, gcc.dg/c90-const-expr-6.c,
gcc.dg/c90-const-expr-7.c, gcc.dg/c90-const-expr-8.c,
gcc.dg/c90-const-expr-9.c, gcc.dg/c90-const-expr-10.c,
gcc.dg/c90-const-expr-11.c, gcc.dg/c99-const-expr-6.c,
gcc.dg/c99-const-expr-7.c, gcc.dg/c99-const-expr-8.c,
gcc.dg/c99-const-expr-9.c, gcc.dg/c99-const-expr-10.c,
gcc.dg/c99-const-expr-11.c, gcc.dg/c99-const-expr-12.c,
gcc.dg/c99-const-expr-13.c, gcc.dg/compare10.c,
gcc.dg/gnu89-const-expr-1.c, gcc.dg/gnu89-const-expr-2.c,
gcc.dg/gnu99-const-expr-1.c, gcc.dg/gnu99-const-expr-2.c,
gcc.dg/gnu99-const-expr-3.c, gcc.dg/vla-12.c, gcc.dg/vla-13.c,
gcc.dg/vla-14.c, gcc.dg/vla-15.c, gcc.dg/vla-16.c: New tests.
* gcc.dg/c90-const-expr-1.c, gcc.dg/c90-const-expr-2.c,
gcc.dg/c90-const-expr-3.c, gcc.dg/c99-const-expr-2.c,
gcc.dg/c99-const-expr-3.c, gcc.dg/c99-static-1.c: Remove XFAILs.
* gcc.dg/c90-const-expr-2.c: Use ZERO in place of 0 in another
case.
* gcc.dg/overflow-warn-1.c, gcc.dg/overflow-warn-2.c,
gcc.dg/overflow-warn-3.c, gcc.dg/overflow-warn-4.c: Remove
XFAILs. Update expected messages.
* gcc.dg/pr14649-1.c, gcc.dg/pr19984.c, gcc.dg/pr25682.c: Update
expected messages.
* gcc.dg/real-const-1.c: Replace with test from original PR.
* gcc.dg/vect/pr32230.c: Use intermediate cast to __PTRDIFF_TYPE__
when casting from non-constant integer to pointer.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145254 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gcc.dg')
43 files changed, 1076 insertions, 66 deletions
diff --git a/gcc/testsuite/gcc.dg/bconstp-2.c b/gcc/testsuite/gcc.dg/bconstp-2.c new file mode 100644 index 00000000000..5b5ff8b1cf1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bconstp-2.c @@ -0,0 +1,27 @@ +/* As bconstp-1.c, but with the __builtin_constant_p calls + parenthesized. */ +/* { dg-do compile } */ + +/* This test checks that builtin_constant_p can be used safely in + initializers for static data. The macro X() defined below should + be an acceptable initializer expression no matter how complex its + argument is. */ + +extern int a; +extern int b; + +extern int foo(void); +extern int bar(void); + +#define X(exp) ((__builtin_constant_p(exp)) ? (exp) : -1) + +const short tests[] = { + X(0), + X(a), + X(0 && a), + X(a && b), + X(foo()), + X(0 && foo()), + X(a && foo()), + X(foo() && bar()) +}; diff --git a/gcc/testsuite/gcc.dg/bconstp-3.c b/gcc/testsuite/gcc.dg/bconstp-3.c new file mode 100644 index 00000000000..9e3d10f3993 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bconstp-3.c @@ -0,0 +1,27 @@ +/* As bconstp-1.c, but with the __builtin_constant_p calls inside + __builtin_choose_expr. */ +/* { dg-do compile } */ + +/* This test checks that builtin_constant_p can be used safely in + initializers for static data. The macro X() defined below should + be an acceptable initializer expression no matter how complex its + argument is. */ + +extern int a; +extern int b; + +extern int foo(void); +extern int bar(void); + +#define X(exp) (__builtin_choose_expr(1, __builtin_constant_p(exp), 1) ? (exp) : -1) + +const short tests[] = { + X(0), + X(a), + X(0 && a), + X(a && b), + X(foo()), + X(0 && foo()), + X(a && foo()), + X(foo() && bar()) +}; diff --git a/gcc/testsuite/gcc.dg/bconstp-4.c b/gcc/testsuite/gcc.dg/bconstp-4.c new file mode 100644 index 00000000000..bb8aef19fc0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bconstp-4.c @@ -0,0 +1,10 @@ +/* Test that a condition is not counted as a call to + __builtin_constant_p if that call is itself inside a conditional + expression with __builtin_constant_p condition. */ +/* { dg-do compile } */ + +extern int foo(void); + +#define X(exp) (__builtin_choose_expr(1, __builtin_constant_p(exp), 1) ? (exp) : -1) + +const int x = ((__builtin_constant_p(1) ? __builtin_constant_p (0 && foo()) : 0) ? (0 && foo()) : -1); /* { dg-error "initializer element is not a constant expression" } */ diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-1.c b/gcc/testsuite/gcc.dg/c90-const-expr-1.c index 96d19ee8164..e4c27ac4561 100644 --- a/gcc/testsuite/gcc.dg/c90-const-expr-1.c +++ b/gcc/testsuite/gcc.dg/c90-const-expr-1.c @@ -15,9 +15,9 @@ void foo (void) { int i; - static int j = (1 ? 0 : (i = 2)); /* { dg-error "initial" "assignment" { xfail *-*-* } } */ - static int k = (1 ? 0 : ++i); /* { dg-error "initial" "increment" { xfail *-*-* } } */ - static int l = (1 ? 0 : --i); /* { dg-error "initial" "decrement" { xfail *-*-* } } */ - static int m = (1 ? 0 : bar ()); /* { dg-error "initial" "function call" { xfail *-*-* } } */ - static int n = (1 ? 0 : (2, 3)); /* { dg-error "initial" "comma" { xfail *-*-* } } */ + static int j = (1 ? 0 : (i = 2)); /* { dg-error "initial" "assignment" } */ + static int k = (1 ? 0 : ++i); /* { dg-error "initial" "increment" } */ + static int l = (1 ? 0 : --i); /* { dg-error "initial" "decrement" } */ + static int m = (1 ? 0 : bar ()); /* { dg-error "initial" "function call" } */ + static int n = (1 ? 0 : (2, 3)); /* { dg-error "initial" "comma" } */ } diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-10.c b/gcc/testsuite/gcc.dg/c90-const-expr-10.c new file mode 100644 index 00000000000..6159390bb94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-10.c @@ -0,0 +1,28 @@ +/* Test for constant expressions: invalid null pointer constants in + various contexts (make sure NOPs are not inappropriately + stripped). */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +void *p = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ +struct s { void *a; } q = { (__SIZE_TYPE__)(void *)0 }; /* { dg-error "without a cast" } */ +void * +f (void) +{ + void *r; + r = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ + return (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ +} +void g (void *); /* { dg-message "but argument is of type" } */ +void +h (void) +{ + g ((__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */ +} +void g2 (int, void *); /* { dg-message "but argument is of type" } */ +void +h2 (void) +{ + g2 (0, (__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */ +} diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-11.c b/gcc/testsuite/gcc.dg/c90-const-expr-11.c new file mode 100644 index 00000000000..cfda93e12a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-11.c @@ -0,0 +1,27 @@ +/* Test for constant expressions: C90 aggregate initializers requiring + constant expressions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors -O2" } */ + +#include <float.h> +#include <limits.h> + +double atan(double); + +struct s { double d; }; +struct t { int i; }; + +void +f (void) +{ + /* As in PR 14649 for static initializers. */ + struct s a = { atan (1.0) }; /* { dg-error "is not a constant expression|near initialization" } */ + /* Overflow. */ + struct t b = { INT_MAX + 1 }; /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ + struct t c = { DBL_MAX }; /* { dg-warning "overflow in implicit constant conversion" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 23 } */ + /* Bad operator outside sizeof. */ + struct s d = { 1 ? 1.0 : atan (a.d) }; /* { dg-error "is not a constant expression|near initialization" } */ +} diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-2.c b/gcc/testsuite/gcc.dg/c90-const-expr-2.c index cad5bc8673b..662d8e790dc 100644 --- a/gcc/testsuite/gcc.dg/c90-const-expr-2.c +++ b/gcc/testsuite/gcc.dg/c90-const-expr-2.c @@ -34,10 +34,10 @@ foo (void) { ASSERT_NPC (0); ASSERT_NPC ((void *)0); - ASSERT_NOT_NPC ((void *)(void *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((void *)(char *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((void *)(void *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((void *)(char *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NOT_NPC ((void *)(0, ZERO)); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ - ASSERT_NOT_NPC ((void *)(&"Foobar"[0] - &"Foobar"[0])); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((void *)(&"Foobar"[0] - &"Foobar"[0])); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ /* This last one is a null pointer constant in C99 only. */ - ASSERT_NOT_NPC ((void *)(1 ? 0 : (0, 0))); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((void *)(1 ? ZERO : (0, ZERO))); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ } diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-3.c b/gcc/testsuite/gcc.dg/c90-const-expr-3.c index 0fda68e82b7..46a02273445 100644 --- a/gcc/testsuite/gcc.dg/c90-const-expr-3.c +++ b/gcc/testsuite/gcc.dg/c90-const-expr-3.c @@ -28,19 +28,19 @@ foo (void) ASSERT_NPC (0); ASSERT_NOT_NPC (ZERO); ASSERT_NPC (0 + 0); - ASSERT_NOT_NPC (ZERO + 0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC (ZERO + ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (ZERO + 0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC (ZERO + ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC (+0); - ASSERT_NOT_NPC (+ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (+ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC (-0); - ASSERT_NOT_NPC (-ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (-ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC ((char) 0); ASSERT_NOT_NPC ((char) ZERO); ASSERT_NPC ((int) 0); ASSERT_NOT_NPC ((int) ZERO); ASSERT_NPC ((int) 0.0); ASSERT_NOT_NPC ((int) DZERO); - ASSERT_NOT_NPC ((int) +0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((int) (0.0+0.0)); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((int) (double)0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((int) +0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((int) (0.0+0.0)); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((int) (double)0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ } diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-6.c b/gcc/testsuite/gcc.dg/c90-const-expr-6.c new file mode 100644 index 00000000000..50de3a9525f --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-6.c @@ -0,0 +1,53 @@ +/* Test for constant expressions: operands and casts not permitted in + integer constant expressions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +/* PR 29116. */ +int n = 0, p[n * 0 + 1]; /* { dg-error "variabl|can't be evaluated" } */ + +/* PR 31871. */ +extern int c[1 + ((__PTRDIFF_TYPE__) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */ + +/* Implicit conversions from floating-point constants are not OK, + although explicit ones are. */ +extern int c1[1.0 ? 1 : 0]; /* { dg-error "variab|can't be evaluated" } */ + +extern int c2[(int)1.0 ? 1 : 0]; + +extern int c3[1.0 && 1]; /* { dg-error "variab|can't be evaluated" } */ + +extern int c4[(int)1.0 && 1]; + +extern int c5[1.0 || 1]; /* { dg-error "variab|can't be evaluated" } */ + +extern int c6[(int)1.0 || 1]; + +/* Similar with various other cases where integer constant expressions + are required. */ + +struct s { + int a : (n * 0 + 1); /* { dg-error "constant" } */ +}; + +enum e { + E = (1 + ((__PTRDIFF_TYPE__) (void *) 0)), /* { dg-error "constant" } */ + E2 = 0 +}; + +enum f { + F = (1 ? 1 : n), /* { dg-error "constant" } */ + F2 = 0 +}; + +void +f (int a) +{ + int v[1 + ((__PTRDIFF_TYPE__) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */ + switch (a) + { + case (n * 0 + 1): /* { dg-error "constant" } */ + ; + } +} diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-7.c b/gcc/testsuite/gcc.dg/c90-const-expr-7.c new file mode 100644 index 00000000000..30aeba06a7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-7.c @@ -0,0 +1,35 @@ +/* Test for constant expressions: overflow and constant expressions; + see also overflow-warn-*.c for some other cases. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +#include <float.h> + +int a = DBL_MAX; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 9 } */ +int b = (int) DBL_MAX; /* { dg-error "overflow" "" } */ +unsigned int c = -1.0; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 12 } */ +unsigned int d = (unsigned)-1.0; /* { dg-error "overflow" } */ + +int e = 0 << 1000; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 16 } */ +int f = 0 << -1; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 18 } */ +int g = 0 >> 1000; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 20 } */ +int h = 0 >> -1; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 22 } */ + +int b1 = (0 ? (int) DBL_MAX : 0); +unsigned int d1 = (0 ? (unsigned int)-1.0 : 0); +int e1 = (0 ? 0 << 1000 : 0); +int f1 = (0 ? 0 << -1 : 0); +int g1 = (0 ? 0 >> 1000 : 0); +int h1 = (0 ? 0 >> -1: 0); + +int i = -1 << 0; + +int j[1] = { DBL_MAX }; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 34 } */ diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-8.c b/gcc/testsuite/gcc.dg/c90-const-expr-8.c new file mode 100644 index 00000000000..966044c4eff --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-8.c @@ -0,0 +1,27 @@ +/* Test for constant expressions: overflow and constant expressions + with -fwrapv: overflows still count as such for the purposes of + constant expressions even when they have defined values at + runtime. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors -fwrapv" } */ + +#include <limits.h> + +enum e { + E0 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 12 } */ + E1 = 0 * (INT_MIN / -1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 14 } */ + E2 = 0 * (INT_MAX * INT_MAX), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 16 } */ + E3 = 0 * (INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 18 } */ + E4 = 0 * (unsigned)(INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 20 } */ + E5 = 0 * -INT_MIN, /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */ + E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */ + E7 = INT_MIN % -1 /* Not an overflow. */ +}; diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-9.c b/gcc/testsuite/gcc.dg/c90-const-expr-9.c new file mode 100644 index 00000000000..d9ab3756599 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-const-expr-9.c @@ -0,0 +1,26 @@ +/* Test for constant expressions: __builtin_offsetof allowed in + integer constant expressions but not traditional offsetof + expansion. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +struct s { + int a; +}; + +struct t { + struct s a; + int b[2]; +}; + +#define old_offsetof(TYPE, MEMBER) ((__SIZE_TYPE__) &((TYPE *)0)->MEMBER) + +enum e { + E1 = old_offsetof (struct s, a), /* { dg-error "constant" } */ + E2 = old_offsetof (struct t, a.a), /* { dg-error "constant" } */ + E3 = old_offsetof (struct t, b[1]), /* { dg-error "constant" } */ + E4 = __builtin_offsetof (struct s, a), + E5 = __builtin_offsetof (struct t, a.a), + E6 = __builtin_offsetof (struct t, b[1]) +}; diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-10.c b/gcc/testsuite/gcc.dg/c99-const-expr-10.c new file mode 100644 index 00000000000..8e5a1043d29 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-10.c @@ -0,0 +1,28 @@ +/* Test for constant expressions: invalid null pointer constants in + various contexts (make sure NOPs are not inappropriately + stripped). */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +void *p = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ +struct s { void *a; } q = { (__SIZE_TYPE__)(void *)0 }; /* { dg-error "without a cast" } */ +void * +f (void) +{ + void *r; + r = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ + return (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */ +} +void g (void *); /* { dg-message "but argument is of type" } */ +void +h (void) +{ + g ((__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */ +} +void g2 (int, void *); /* { dg-message "but argument is of type" } */ +void +h2 (void) +{ + g2 (0, (__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */ +} diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-11.c b/gcc/testsuite/gcc.dg/c99-const-expr-11.c new file mode 100644 index 00000000000..21d9c5f46a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-11.c @@ -0,0 +1,46 @@ +/* Test for constant expressions: cases involving VLAs. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +/* It appears address constants may contain casts to variably modified + types. Whether they should be permitted was discussed in + <http://groups.google.com/group/comp.std.c/msg/923eee5ab690fd98> + <LV7g2Vy3ARF$Ew9Q@romana.davros.org>; since static pointers to VLAs + are definitely permitted within functions and may be initialized + and such initialization involves implicit conversion to a variably + modified type, allowing explicit casts seems appropriate. Thus, + GCC allows them as long as the "evaluated" size expressions do not + contain the various operators not permitted to be evaluated in a + constant expression, and as long as the result is genuinely + constant (meaning that pointer arithmetic using the size of the VLA + is generally not permitted). */ + +static int sa[100]; + +volatile int nv; + +int +f (int m, int n) +{ + static int (*a1)[n] = &sa; + static int (*a2)[n] = (int (*)[n])sa; + static int (*a3)[n] = (int (*)[(int){n}])sa; + static int (*a4)[n] = (int (*)[(int){m++}])sa; /* { dg-error "constant" } */ + static int (*a5)[n] = (int (*)[(int){++m}])sa; /* { dg-error "constant" } */ + static int (*a6)[n] = (int (*)[(int){m--}])sa; /* { dg-error "constant" } */ + static int (*a7)[n] = (int (*)[(int){--m}])sa; /* { dg-error "constant" } */ + static int (*a8)[n] = (int (*)[(m=n)])sa; /* { dg-error "constant" } */ + static int (*a9)[n] = (int (*)[(m+=n)])sa; /* { dg-error "constant" } */ + static int (*a10)[n] = (int (*)[f(m,n)])sa; /* { dg-error "constant" } */ + static int (*a11)[n] = (int (*)[(m,n)])sa; /* { dg-error "constant" } */ + static int (*a12)[n] = (int (*)[sizeof(int[n])])sa; + static int (*a13)[n] = (int (*)[sizeof(int[m++])])sa; /* { dg-error "constant" } */ + static int (*a14)[n] = (int (*)[sizeof(*a1)])sa; + static int (*a15)[n] = (int (*)[sizeof(*(int (*)[n])sa)])sa; + static int (*a16)[n] = (int (*)[sizeof(*(int (*)[m++])sa)])sa; /* { dg-error "constant" } */ + static int (*a17)[n] = (int (*)[nv])sa; + typedef int (*vmt)[m++]; + static int (*a18)[n] = (vmt)sa; + return n; +} diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-12.c b/gcc/testsuite/gcc.dg/c99-const-expr-12.c new file mode 100644 index 00000000000..396cea51acc --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-12.c @@ -0,0 +1,23 @@ +/* Test for constant expressions: VLA size constraints. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +void +f (int m) +{ + /* An array size that is a constant expression, not just an integer + constant expression, must be checked for being positive, but only + an integer constant expression makes it not a VLA (which affects + certain compatibility checks, in particular). */ + int a1[0]; /* { dg-error "zero" } */ + int a2[-1]; /* { dg-error "negative" } */ + int a3[(int)(double)0.0]; /* { dg-error "zero" } */ + int a4[(int)-1.0]; /* { dg-error "negative" } */ + int a5[(int)+1.0]; + int a6[(int)+2.0]; + void *p = (m ? &a5 : &a6); + int a7[(int)1.0]; + int a8[(int)2.0]; + void *q = (m ? &a7 : &a8); /* { dg-error "pointer type mismatch in conditional expression" } */ +} diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-13.c b/gcc/testsuite/gcc.dg/c99-const-expr-13.c new file mode 100644 index 00000000000..0ee525bec61 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-13.c @@ -0,0 +1,15 @@ +/* Test for constant expressions: VLA size constraints with + -frounding-math. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors -frounding-math" } */ + +void +f (void) +{ + /* With -frounding-math, presume that floating-point expressions + that may depend on the rounding mode do not count as arithmetic + constant expressions, and so arrays involving such expressions in + their sizes do not have the size checked for being negative. */ + int a1[(int)(-5.0/3.0)]; +} diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-2.c b/gcc/testsuite/gcc.dg/c99-const-expr-2.c index 555a58c0a63..8e5a600185f 100644 --- a/gcc/testsuite/gcc.dg/c99-const-expr-2.c +++ b/gcc/testsuite/gcc.dg/c99-const-expr-2.c @@ -34,10 +34,10 @@ foo (void) { ASSERT_NPC (0); ASSERT_NPC ((void *)0); - ASSERT_NOT_NPC ((void *)(void *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((void *)(char *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((void *)(void *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((void *)(char *)0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NOT_NPC ((void *)(0, ZERO)); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ - ASSERT_NOT_NPC ((void *)(&"Foobar"[0] - &"Foobar"[0])); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((void *)(&"Foobar"[0] - &"Foobar"[0])); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ /* This last one is a null pointer constant in C99 only. */ ASSERT_NPC ((void *)(1 ? 0 : (0, 0))); } diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-3.c b/gcc/testsuite/gcc.dg/c99-const-expr-3.c index f230603332b..9b036a32d16 100644 --- a/gcc/testsuite/gcc.dg/c99-const-expr-3.c +++ b/gcc/testsuite/gcc.dg/c99-const-expr-3.c @@ -27,19 +27,19 @@ foo (void) ASSERT_NPC (0); ASSERT_NOT_NPC (ZERO); ASSERT_NPC (0 + 0); - ASSERT_NOT_NPC (ZERO + 0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC (ZERO + ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (ZERO + 0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC (ZERO + ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC (+0); - ASSERT_NOT_NPC (+ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (+ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC (-0); - ASSERT_NOT_NPC (-ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC (-ZERO); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ ASSERT_NPC ((char) 0); ASSERT_NOT_NPC ((char) ZERO); ASSERT_NPC ((int) 0); ASSERT_NOT_NPC ((int) ZERO); ASSERT_NPC ((int) 0.0); ASSERT_NOT_NPC ((int) DZERO); - ASSERT_NOT_NPC ((int) +0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((int) (0.0+0.0)); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ - ASSERT_NOT_NPC ((int) (double)0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" { xfail *-*-* } } */ + ASSERT_NOT_NPC ((int) +0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((int) (0.0+0.0)); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ + ASSERT_NOT_NPC ((int) (double)0.0); /* { dg-bogus "incompatible" "bogus null pointer constant" } */ } diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-6.c b/gcc/testsuite/gcc.dg/c99-const-expr-6.c new file mode 100644 index 00000000000..1a31ddc40c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-6.c @@ -0,0 +1,62 @@ +/* Test for constant expressions: operands and casts not permitted in + integer constant expressions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +/* PR 29116. */ +int n = 0, p[n * 0 + 1]; /* { dg-error "variabl" } */ + +/* PR 31871. */ +extern int c[1 + ((__PTRDIFF_TYPE__) (void *) 0)]; /* { dg-error "variab" } */ + +/* Implicit conversions from floating-point constants are not OK, + although explicit ones are. */ +extern int c1[1.0 ? 1 : 0]; /* { dg-error "variab" } */ + +extern int c2[(int)1.0 ? 1 : 0]; + +extern int c3[1.0 && 1]; /* { dg-error "variab" } */ + +extern int c4[(int)1.0 && 1]; + +extern int c5[1.0 || 1]; /* { dg-error "variab" } */ + +extern int c6[(int)1.0 || 1]; + +/* Similar with various other cases where integer constant expressions + are required. */ + +struct s { + int a : (n * 0 + 1); /* { dg-error "constant" } */ +}; + +enum e { + E = (1 + ((__PTRDIFF_TYPE__) (void *) 0)), /* { dg-error "constant" } */ + E2 = 0 +}; + +enum f { + F = (1 ? 1 : n), /* { dg-error "constant" } */ + F2 = 0 +}; + +/* Presume that a compound literal, being a reference to an anonymous + variable, is not allowed in an integer constant expression + regardless of what initializers it contains. */ +enum g { + G = (1 ? 1 : (int){0}), /* { dg-error "constant" } */ + G2 = 0 +}; + +int v[2] = { [(n * 0 + 1)] = 1 }; /* { dg-error "constant|near initialization" } */ + +void +f (int a) +{ + switch (a) + { + case (n * 0 + 1): /* { dg-error "constant" } */ + ; + } +} diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-7.c b/gcc/testsuite/gcc.dg/c99-const-expr-7.c new file mode 100644 index 00000000000..b872077e964 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-7.c @@ -0,0 +1,43 @@ +/* Test for constant expressions: overflow and constant expressions; + see also overflow-warn-*.c for some other cases. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +#include <float.h> +#include <limits.h> + +int a = DBL_MAX; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 10 } */ +int b = (int) DBL_MAX; /* { dg-error "overflow" "" } */ +unsigned int c = -1.0; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 13 } */ +unsigned int d = (unsigned)-1.0; /* { dg-error "overflow" } */ + +int e = 0 << 1000; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 17 } */ +int f = 0 << -1; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 19 } */ +int g = 0 >> 1000; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 21 } */ +int h = 0 >> -1; /* { dg-warning "shift count" } */ +/* { dg-error "constant" "constant" { target *-*-* } 23 } */ + +int b1 = (0 ? (int) DBL_MAX : 0); +unsigned int d1 = (0 ? (unsigned int)-1.0 : 0); +int e1 = (0 ? 0 << 1000 : 0); +int f1 = (0 ? 0 << -1 : 0); +int g1 = (0 ? 0 >> 1000 : 0); +int h1 = (0 ? 0 >> -1: 0); + +/* Allowed for now, but actually undefined behavior in C99. */ +int i = -1 << 0; + +int j[1] = { DBL_MAX }; /* { dg-warning "overflow in implicit constant conversion" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 36 } */ + +int array[2] = { [0 * (INT_MAX + 1)] = 0 }; /* { dg-warning "integer overflow in expression" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 39 } */ + +_Bool k = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 42 } */ diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-8.c b/gcc/testsuite/gcc.dg/c99-const-expr-8.c new file mode 100644 index 00000000000..e84fa7b4db0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-8.c @@ -0,0 +1,27 @@ +/* Test for constant expressions: overflow and constant expressions + with -fwrapv: overflows still count as such for the purposes of + constant expressions even when they have defined values at + runtime. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors -fwrapv" } */ + +#include <limits.h> + +enum e { + E0 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 12 } */ + E1 = 0 * (INT_MIN / -1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 14 } */ + E2 = 0 * (INT_MAX * INT_MAX), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 16 } */ + E3 = 0 * (INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 18 } */ + E4 = 0 * (unsigned)(INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 20 } */ + E5 = 0 * -INT_MIN, /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */ + E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */ + E7 = INT_MIN % -1 /* Not an overflow. */ +}; diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-9.c b/gcc/testsuite/gcc.dg/c99-const-expr-9.c new file mode 100644 index 00000000000..48f43edece6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-9.c @@ -0,0 +1,26 @@ +/* Test for constant expressions: __builtin_offsetof allowed in + integer constant expressions but not traditional offsetof + expansion. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +struct s { + int a; +}; + +struct t { + struct s a; + int b[2]; +}; + +#define old_offsetof(TYPE, MEMBER) ((__SIZE_TYPE__) &((TYPE *)0)->MEMBER) + +enum e { + E1 = old_offsetof (struct s, a), /* { dg-error "constant" } */ + E2 = old_offsetof (struct t, a.a), /* { dg-error "constant" } */ + E3 = old_offsetof (struct t, b[1]), /* { dg-error "constant" } */ + E4 = __builtin_offsetof (struct s, a), + E5 = __builtin_offsetof (struct t, a.a), + E6 = __builtin_offsetof (struct t, b[1]) +}; diff --git a/gcc/testsuite/gcc.dg/c99-static-1.c b/gcc/testsuite/gcc.dg/c99-static-1.c index 3c817c624d4..a138f878d92 100644 --- a/gcc/testsuite/gcc.dg/c99-static-1.c +++ b/gcc/testsuite/gcc.dg/c99-static-1.c @@ -27,7 +27,7 @@ static int f4(void); void g4(void) { sizeof(int (*)[f4()]); } /* Constraint violation (VLA). */ -static int f5(void); /* { dg-error "used but never defined" "VLA" { xfail *-*-* } } */ +static int f5(void); /* { dg-error "used but never defined" "VLA" } */ void g5(void) { sizeof(int [0 ? f5() : 1]); } /* OK (non-constant sizeof inside constant sizeof). */ diff --git a/gcc/testsuite/gcc.dg/compare10.c b/gcc/testsuite/gcc.dg/compare10.c new file mode 100644 index 00000000000..3b8af28bf18 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compare10.c @@ -0,0 +1,16 @@ +/* Test for bogus -Wsign-compare warnings that appeared when not + folding operands before warning. */ +/* { dg-do compile } */ +/* { dg-options "-Wsign-compare" } */ + +int +test_compare (int a, unsigned b) +{ + return (b > 8 * (a ? 4 : 8)); +} + +unsigned int +test_conditional (int a, unsigned b, int c) +{ + return (c ? b : 8 * (a ? 4 : 8)); +} diff --git a/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c b/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c new file mode 100644 index 00000000000..ebc68859a5e --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu89-const-expr-1.c @@ -0,0 +1,47 @@ +/* Test for constant expressions: GNU extensions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89" } */ + +int n; + +void +f (void) +{ + int i = 0; + int a[n]; + enum e1 { + /* Integer constant expressions may not contain statement + expressions (not a permitted operand). */ + E1 = (1 ? 0 : ({ 0; })), /* { dg-error "constant" } */ + /* Real and imaginary parts act like other arithmetic + operators. */ + E2 = __real__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E3 = __real__ 0, + E4 = __imag__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E5 = __imag__ 0, + /* __alignof__ always constant. */ + E6 = __alignof__ (int[n]), + E7 = __alignof__ (a), + /* __extension__ ignored for constant expression purposes. */ + E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E9 = __extension__ 0, + /* Conditional expressions with omitted arguments act like the + standard type. */ + E10 = (1 ? : i++), /* { dg-error "constant" } */ + E11 = (1 ? : 0) + }; + enum e2 { + /* Complex integer constants may be cast directly to integer + types, but not after further arithmetic on them. */ + F1 = (int) (_Complex int) 2i, /* { dg-error "constant" } */ + F2 = (int) +2i, /* { dg-error "constant" } */ + F3 = (int) (1 + 2i), /* { dg-error "constant" } */ + F4 = (int) 2i + }; + static double dr = __real__ (1.0 + 2.0i); + static double di = __imag__ (1.0 + 2.0i); + /* Statement expressions allowed in unevaluated subexpressions in + initializers in gnu99 but not gnu89. */ + static int j = (1 ? 0 : ({ 0; })); /* { dg-warning "constant expression" } */ +} diff --git a/gcc/testsuite/gcc.dg/gnu89-const-expr-2.c b/gcc/testsuite/gcc.dg/gnu89-const-expr-2.c new file mode 100644 index 00000000000..3395b55c733 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu89-const-expr-2.c @@ -0,0 +1,23 @@ +/* Test for constant expressions: __builtin_choose_expr. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89 -pedantic-errors" } */ + +#include <limits.h> + +int a, b, c; + +void +f (void) +{ + /* __builtin_choose_expr acts exactly like the chosen argument for + all constant expression purposes. */ + enum e { + E1 = __builtin_choose_expr (1, 1, ++b) + }; + /* The first argument to __builtin_choose_expr must be an integer + constant expression. */ + a = __builtin_choose_expr ((void *)0, b, c); /* { dg-error "constant" } */ + a = __builtin_choose_expr (0 * (INT_MAX + 1), b, c); /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ +} diff --git a/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c b/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c new file mode 100644 index 00000000000..dcc976e5582 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu99-const-expr-1.c @@ -0,0 +1,47 @@ +/* Test for constant expressions: GNU extensions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +int n; + +void +f (void) +{ + int i = 0; + int a[n]; + enum e1 { + /* Integer constant expressions may not contain statement + expressions (not a permitted operand). */ + E1 = (1 ? 0 : ({ 0; })), /* { dg-error "constant" } */ + /* Real and imaginary parts act like other arithmetic + operators. */ + E2 = __real__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E3 = __real__ 0, + E4 = __imag__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E5 = __imag__ 0, + /* __alignof__ always constant. */ + E6 = __alignof__ (int[n]), + E7 = __alignof__ (a), + /* __extension__ ignored for constant expression purposes. */ + E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant" } */ + E9 = __extension__ 0, + /* Conditional expressions with omitted arguments act like the + standard type. */ + E10 = (1 ? : i++), /* { dg-error "constant" } */ + E11 = (1 ? : 0) + }; + enum e2 { + /* Complex integer constants may be cast directly to integer + types, but not after further arithmetic on them. */ + F1 = (int) (_Complex int) 2i, /* { dg-error "constant" } */ + F2 = (int) +2i, /* { dg-error "constant" } */ + F3 = (int) (1 + 2i), /* { dg-error "constant" } */ + F4 = (int) 2i + }; + static double dr = __real__ (1.0 + 2.0i); + static double di = __imag__ (1.0 + 2.0i); + /* Statement expressions allowed in unevaluated subexpressions in + initializers in gnu99 but not gnu89. */ + static int j = (1 ? 0 : ({ 0; })); +} diff --git a/gcc/testsuite/gcc.dg/gnu99-const-expr-2.c b/gcc/testsuite/gcc.dg/gnu99-const-expr-2.c new file mode 100644 index 00000000000..f868c537fa2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu99-const-expr-2.c @@ -0,0 +1,23 @@ +/* Test for constant expressions: __builtin_choose_expr. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -pedantic-errors" } */ + +#include <limits.h> + +int a, b, c; + +void +f (void) +{ + /* __builtin_choose_expr acts exactly like the chosen argument for + all constant expression purposes. */ + enum e { + E1 = __builtin_choose_expr (1, 1, ++b) + }; + /* The first argument to __builtin_choose_expr must be an integer + constant expression. */ + a = __builtin_choose_expr ((void *)0, b, c); /* { dg-error "constant" } */ + a = __builtin_choose_expr (0 * (INT_MAX + 1), b, c); /* { dg-warning "integer overflow in expression" } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ +} diff --git a/gcc/testsuite/gcc.dg/gnu99-const-expr-3.c b/gcc/testsuite/gcc.dg/gnu99-const-expr-3.c new file mode 100644 index 00000000000..aba7da542a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu99-const-expr-3.c @@ -0,0 +1,32 @@ +/* Test for constant expressions: cases involving VLAs and typeof. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -pedantic-errors" } */ + +/* It appears address constants may contain casts to variably modified + types. Whether they should be permitted was discussed in + <http://groups.google.com/group/comp.std.c/msg/923eee5ab690fd98> + <LV7g2Vy3ARF$Ew9Q@romana.davros.org>; since static pointers to VLAs + are definitely permitted within functions and may be initialized + and such initialization involves implicit conversion to a variably + modified type, allowing explicit casts seems appropriate. Thus, + GCC allows them as long as the "evaluated" size expressions do not + contain the various operators not permitted to be evaluated in a + constant expression, and as long as the result is genuinely + constant (meaning that pointer arithmetic using the size of the VLA + is generally not permitted). */ + +static int sa[100]; + +int +f (int m, int n) +{ + static int (*a1)[n] = &sa; + static int (*a2)[n] = (__typeof__(int (*)[n]))sa; + static int (*a3)[n] = (__typeof__(int (*)[(int){m++}]))sa; /* { dg-error "constant" } */ + static int (*a4)[n] = (__typeof__((int (*)[n])sa))sa; + static int (*a5)[n] = (__typeof__((int (*)[m++])sa))sa; /* { dg-error "constant" } */ + static int (*a6)[n] = (__typeof__((int (*)[100])(int (*)[m++])sa))sa; + static int (*a7)[n] = (__typeof__((int (*)[n])sa + m++))sa; /* { dg-error "constant" } */ + return n; +} diff --git a/gcc/testsuite/gcc.dg/overflow-warn-1.c b/gcc/testsuite/gcc.dg/overflow-warn-1.c index 9f763879f2d..633d70b84b5 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-1.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-1.c @@ -17,7 +17,7 @@ enum e { /* But as in DR#031, the 1/0 in an evaluated subexpression means the whole expression violates the constraints. */ E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ - /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ + /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ /* Again, overflow in evaluated subexpression. */ E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ @@ -28,6 +28,7 @@ enum e { struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ + /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 30 } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ }; @@ -46,9 +47,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "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 makes pointer from integer without a cast" "null" { target *-*-* } 48 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 49 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-warning "initialization makes pointer from integer without a cast" "null" { xfail *-*-* } 50 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } 51 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 51 } */ void *r = (1 ? 0 : INT_MAX+1); void @@ -57,6 +59,7 @@ g (int i) switch (i) { case 0 * (1/0): /* { dg-warning "division by zero" } */ + /* { dg-error "case label does not reduce to an integer constant" "constant" { target *-*-* } 61 } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ ; diff --git a/gcc/testsuite/gcc.dg/overflow-warn-2.c b/gcc/testsuite/gcc.dg/overflow-warn-2.c index 7da84324ad9..e8bbd24455d 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-2.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-2.c @@ -17,7 +17,7 @@ enum e { /* But as in DR#031, the 1/0 in an evaluated subexpression means the whole expression violates the constraints. */ E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ - /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ + /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ /* Again, overflow in evaluated subexpression. */ E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ @@ -28,6 +28,7 @@ enum e { struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ + /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 30 } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ }; @@ -46,9 +47,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "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 makes pointer from integer without a cast" "null" { target *-*-* } 48 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 49 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-warning "initialization makes pointer from integer without a cast" "null" { xfail *-*-* } 50 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } 51 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 51 } */ void *r = (1 ? 0 : INT_MAX+1); void @@ -57,6 +59,7 @@ g (int i) switch (i) { case 0 * (1/0): /* { dg-warning "division by zero" } */ + /* { dg-error "case label does not reduce to an integer constant" "constant" { target *-*-* } 61 } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ ; @@ -82,23 +85,23 @@ void h2 (void) { fsc (SCHAR_MAX + 1); - /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 84 } */ + /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 87 } */ fsc (SCHAR_MIN - 1); /* { dg-warning "overflow in implicit constant conversion" } */ - /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 86 } */ + /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 89 } */ fsc (UCHAR_MAX); - /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 88 } */ + /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 91 } */ fsc (UCHAR_MAX + 1); /* { dg-warning "overflow in implicit constant conversion" } */ - /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 90 } */ + /* { dg-warning "passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 93 } */ fuc (-1); - /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 92 } */ + /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 95 } */ fuc (UCHAR_MAX + 1); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ - /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 94 } */ + /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 97 } */ fuc (SCHAR_MIN); - /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 96 } */ + /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 99 } */ fuc (SCHAR_MIN - 1); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ - /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 98 } */ + /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 101 } */ fuc (-UCHAR_MAX); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ - /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 100 } */ + /* { dg-warning "passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 103 } */ } void fui (unsigned int); @@ -122,11 +125,11 @@ h2i (int x) fsi (UINT_MAX); /* { dg-warning "passing argument 1 of 'fsi' as signed due to prototype" } */ si = UINT_MAX; fui (-1); - /* { dg-warning "passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 124 } */ + /* { dg-warning "passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 127 } */ ui = -1; ui = x ? -1 : 1U; fui (INT_MIN); - /* { dg-warning "passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 128 } */ + /* { dg-warning "passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 131 } */ ui = INT_MIN; ui = x ? INT_MIN : 1U; } diff --git a/gcc/testsuite/gcc.dg/overflow-warn-3.c b/gcc/testsuite/gcc.dg/overflow-warn-3.c index 6b1dc053efd..d9a3ae430db 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-3.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-3.c @@ -17,7 +17,7 @@ enum e { /* But as in DR#031, the 1/0 in an evaluated subexpression means the whole expression violates the constraints. */ E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ - /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ + /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 21 } */ /* Again, overflow in evaluated subexpression. */ @@ -30,8 +30,9 @@ enum e { struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ + /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 32 } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ - /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 33 } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 34 } */ }; void @@ -45,16 +46,17 @@ f (void) /* But this expression does need to be constant. */ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ -/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 47 } */ +/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 48 } */ /* The first two of these involve overflow, so are not null pointer 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 "overflow in constant expression" "constant" { target *-*-* } 53 } */ -/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 53 } */ +/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 54 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 54 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-warning "initialization makes pointer from integer without a cast" "null" { xfail *-*-* } 56 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } 57 } */ +/* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } 57 } */ void *r = (1 ? 0 : INT_MAX+1); void @@ -63,9 +65,10 @@ g (int i) switch (i) { case 0 * (1/0): /* { dg-warning "division by zero" } */ + /* { dg-error "case label does not reduce to an integer constant" "constant" { target *-*-* } 67 } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ - /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 67 } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 70 } */ ; } } diff --git a/gcc/testsuite/gcc.dg/overflow-warn-4.c b/gcc/testsuite/gcc.dg/overflow-warn-4.c index 1e2518f9c73..7b7e23cef4b 100644 --- a/gcc/testsuite/gcc.dg/overflow-warn-4.c +++ b/gcc/testsuite/gcc.dg/overflow-warn-4.c @@ -17,7 +17,7 @@ enum e { /* But as in DR#031, the 1/0 in an evaluated subexpression means the whole expression violates the constraints. */ E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ - /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ + /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ /* Again, overflow in evaluated subexpression. */ @@ -30,8 +30,9 @@ enum e { struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ + /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 32 } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ - /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 33 } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 34 } */ }; void @@ -45,16 +46,17 @@ f (void) /* But this expression does need to be constant. */ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ -/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 47 } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 48 } */ /* The first two of these involve overflow, so are not null pointer 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-error "overflow in constant expression" "constant" { target *-*-* } 53 } */ -/* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } 53 } */ +/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 54 } */ +/* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } 54 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initialization makes pointer from integer without a cast" "null" { xfail *-*-* } 56 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } 57 } */ +/* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } 57 } */ void *r = (1 ? 0 : INT_MAX+1); void @@ -63,9 +65,10 @@ g (int i) switch (i) { case 0 * (1/0): /* { dg-warning "division by zero" } */ + /* { dg-error "case label does not reduce to an integer constant" "constant" { target *-*-* } 67 } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ - /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 67 } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 70 } */ ; } } diff --git a/gcc/testsuite/gcc.dg/pr14649-1.c b/gcc/testsuite/gcc.dg/pr14649-1.c index 83a9f570eef..34f42f08f2c 100644 --- a/gcc/testsuite/gcc.dg/pr14649-1.c +++ b/gcc/testsuite/gcc.dg/pr14649-1.c @@ -4,7 +4,7 @@ double atan(double); -const double pi = 4*atan(1.0); /* { dg-warning "(not constant)|(near initialization)" } */ +const double pi = 4*atan(1.0); /* { dg-warning "not a constant expression" } */ const double ok = 4*__builtin_atan(1.0); diff --git a/gcc/testsuite/gcc.dg/pr19984.c b/gcc/testsuite/gcc.dg/pr19984.c index 1b61d7f76b8..5323c461fb0 100644 --- a/gcc/testsuite/gcc.dg/pr19984.c +++ b/gcc/testsuite/gcc.dg/pr19984.c @@ -5,7 +5,7 @@ double nan (const char *); -const double nok = nan (""); /* { dg-warning "(not constant)|(near initialization)" } */ +const double nok = nan (""); /* { dg-warning "(not a constant)|(near initialization)" } */ const double ok = __builtin_nan (""); diff --git a/gcc/testsuite/gcc.dg/pr25682.c b/gcc/testsuite/gcc.dg/pr25682.c index 4118862a1ff..c99b891f8fa 100644 --- a/gcc/testsuite/gcc.dg/pr25682.c +++ b/gcc/testsuite/gcc.dg/pr25682.c @@ -10,10 +10,10 @@ struct S int b; }; -char c[(char *) &((struct S *) 0)->b - (char *) 0]; -char d[(__SIZE_TYPE__) &((struct S *) 8)->b]; -char e[sizeof (c) == __builtin_offsetof (struct S, b) ? 1 : -1]; -char f[sizeof (d) == __builtin_offsetof (struct S, b) + 8 ? 1 : -1]; +char c[(char *) &((struct S *) 0)->b - (char *) 0]; /* { dg-error "variable-size" } */ +char d[(__SIZE_TYPE__) &((struct S *) 8)->b]; /* { dg-error "variable-size" } */ +char e[sizeof (c) == __builtin_offsetof (struct S, b) ? 1 : -1]; /* { dg-error "variably modified" } */ +char f[sizeof (d) == __builtin_offsetof (struct S, b) + 8 ? 1 : -1]; /* { dg-error "variably modified" } */ extern void bar (char *, char *); diff --git a/gcc/testsuite/gcc.dg/real-const-1.c b/gcc/testsuite/gcc.dg/real-const-1.c index 3e2bbfde8fc..4c7058d17af 100644 --- a/gcc/testsuite/gcc.dg/real-const-1.c +++ b/gcc/testsuite/gcc.dg/real-const-1.c @@ -1,4 +1,5 @@ /* PR middle-end/21781. */ /* { dg-do compile } */ +/* { dg-options "-Wall" } */ -int f[.0e200000000 == 0?1:-1]; +int foo(void) { if (.0e200000000 == 0 ) return 1; } diff --git a/gcc/testsuite/gcc.dg/vect/pr32230.c b/gcc/testsuite/gcc.dg/vect/pr32230.c index ed1e7b14614..bdb290ab4ec 100644 --- a/gcc/testsuite/gcc.dg/vect/pr32230.c +++ b/gcc/testsuite/gcc.dg/vect/pr32230.c @@ -16,7 +16,7 @@ const_f (filter_buffer_t *buf) int i; for (i = 0; i < 10; i++) - ((float*) (&((sbuf_header_t *) ((buf) == (filter_buffer_t *)&(buf)->buf[0]))->buf[0]))[i] = val; + ((float*) (&((sbuf_header_t *) (__PTRDIFF_TYPE__)((buf) == (filter_buffer_t *)&(buf)->buf[0]))->buf[0]))[i] = val; } /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vla-12.c b/gcc/testsuite/gcc.dg/vla-12.c new file mode 100644 index 00000000000..604ea88dc2c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-12.c @@ -0,0 +1,50 @@ +/* Test for typeof evaluation: should be at the appropriate point in + the containing expression rather than just adding a statement. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +extern void exit (int); +extern void abort (void); + +void *p; + +void +f1 (void) +{ + int i = 0, j = -1, k = -1; + /* typeof applied to expression with cast. */ + (j = ++i), (void)(typeof ((int (*)[(k = ++i)])p))p; + if (j != 1 || k != 2 || i != 2) + abort (); +} + +void +f2 (void) +{ + int i = 0, j = -1, k = -1; + /* typeof applied to type. */ + (j = ++i), (void)(typeof (int (*)[(k = ++i)]))p; + if (j != 1 || k != 2 || i != 2) + abort (); +} + +void +f3 (void) +{ + int i = 0, j = -1, k = -1; + void *q; + /* typeof applied to expression with cast that is used. */ + (j = ++i), (void)((typeof (1 + (int (*)[(k = ++i)])p))p); + if (j != 1 || k != 2 || i != 2) + abort (); +} + +int +main (void) +{ + f1 (); + f2 (); + f3 (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/vla-13.c b/gcc/testsuite/gcc.dg/vla-13.c new file mode 100644 index 00000000000..70b63059d72 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-13.c @@ -0,0 +1,99 @@ +/* Test for VLA size evaluation; see PR 35198. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +extern void exit (int); +extern void abort (void); + +int i; +void *p; + +void +f1 (void *x, int j) +{ + p = (int (*)[++i])x; + if (i != j) + abort (); +} + +void +f1c (void *x, int j) +{ + p = (int (*)[++i]){x}; + if (i != j) + abort (); +} + +void +f2 (void *x, int j) +{ + x = (void *)(int (*)[++i])p; + if (i != j) + abort (); +} + +void +f2c (void *x, int j) +{ + x = (void *)(int (*)[++i]){p}; + if (i != j) + abort (); +} + +void +f3 (void *x, int j) +{ + (void)(int (*)[++i])p; + if (i != j) + abort (); +} + +void +f3c (void *x, int j) +{ + (void)(int (*)[++i]){p}; + if (i != j) + abort (); +} + +void +f4 (void *x, int j) +{ + (int (*)[++i])p; + (int (*)[++i])p; + if (i != j) + abort (); +} + +void +f4c (void *x, int j) +{ + (int (*)[++i]){p}; + (int (*)[++i]){p}; + if (i != j) + abort (); +} + +void +f5c (void *x, int j, int k) +{ + (++i, f3c (x, j), (int (*)[++i]){p}); + if (i != k) + abort (); +} + +int +main (void) +{ + f1 (p, 1); + f2 (p, 2); + f3 (p, 3); + f4 (p, 5); + f1c (p, 6); + f2c (p, 7); + f3c (p, 8); + f4c (p, 10); + f5c (p, 12, 13); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/vla-14.c b/gcc/testsuite/gcc.dg/vla-14.c new file mode 100644 index 00000000000..3dbb11ed1a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-14.c @@ -0,0 +1,33 @@ +/* Test for VLA size evaluation in va_arg. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +#include <stdarg.h> + +extern void exit (int); +extern void abort (void); + +int a[10]; +int i = 9; + +void +f (int n, ...) +{ + va_list ap; + void *p; + va_start (ap, n); + p = va_arg (ap, typeof (int (*)[++i])); + if (p != a) + abort (); + if (i != n) + abort (); + va_end (ap); +} + +int +main (void) +{ + f (10, &a); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/vla-15.c b/gcc/testsuite/gcc.dg/vla-15.c new file mode 100644 index 00000000000..800163bc184 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-15.c @@ -0,0 +1,27 @@ +/* Test for VLA size evaluation in sizeof typeof. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +#include <stdarg.h> + +extern void exit (int); +extern void abort (void); + +char a[1]; + +void +f1 (void) +{ + int i = 0; + int j = sizeof (typeof (*(++i, (char (*)[i])a))); + if (i != 1 || j != 1) + abort (); +} + +int +main (void) +{ + f1 (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/vla-16.c b/gcc/testsuite/gcc.dg/vla-16.c new file mode 100644 index 00000000000..05e751af7a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-16.c @@ -0,0 +1,70 @@ +/* Test for modifying and taking addresses of compound literals whose + variably modified types involve typeof. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +#include <stdarg.h> + +extern void exit (int); +extern void abort (void); + +int a[1]; + +void +f1 (void) +{ + int i = 0; + int (**p)[1] = &(typeof (++i, (int (*)[i])a)){&a}; + if (*p != &a) + abort (); + if (i != 1) + abort (); +} + +void +f2 (void) +{ + int i = 0; + (typeof (++i, (int (*)[i])a)){&a} = 0; + if (i != 1) + abort (); +} + +void +f3 (void) +{ + int i = 0; + (typeof (++i, (int (*)[i])a)){&a} += 1; + if (i != 1) + abort (); +} + +void +f4 (void) +{ + int i = 0; + --(typeof (++i, (int (*)[i])a)){&a + 1}; + if (i != 1) + abort (); +} + +void +f5 (void) +{ + int i = 0; + (typeof (++i, (int (*)[i])a)){&a}++; + if (i != 1) + abort (); +} + +int +main (void) +{ + f1 (); + f2 (); + f3 (); + f4 (); + f5 (); + exit (0); +} |