Files
clang-p2996/clang/test/Sema/struct-decl.c
Richard Smith 552c6c2328 PR44406: Follow behavior of array bound constant folding in more recent versions of GCC.
Old GCC used to aggressively fold VLAs to constant-bound arrays at block
scope in GNU mode. That's non-conforming, and more modern versions of
GCC only do this at file scope. Update Clang to do the same.

Also promote the warning for this from off-by-default to on-by-default
in all cases; more recent versions of GCC likewise warn on this by
default.

This is still slightly more permissive than GCC, as pointed out in
PR44406, as we still fold VLAs to constant arrays in structs, but that
seems justifiable given that we don't support VLA-in-struct (and don't
intend to ever support it), but GCC does.

Differential Revision: https://reviews.llvm.org/D89523
2020-10-16 14:34:35 -07:00

113 lines
2.9 KiB
C

// RUN: %clang_cc1 -Wno-pointer-to-int-cast -fsyntax-only -verify %s
// PR3459
struct bar {
char n[1];
};
struct foo {
char name[(int)&((struct bar *)0)->n]; // expected-warning {{folded to constant}}
char name2[(int)&((struct bar *)0)->n - 1]; // expected-error {{array size is negative}}
};
// PR3430
struct s {
struct st {
int v;
} *ts;
};
struct st;
int foo() {
struct st *f;
return f->v + f[0].v;
}
// PR3642, PR3671
struct pppoe_tag {
short tag_type;
char tag_data[];
};
struct datatag {
struct pppoe_tag hdr; //expected-warning{{field 'hdr' with variable sized type 'struct pppoe_tag' not at the end of a struct or class is a GNU extension}}
char data;
};
// PR4092
struct s0 {
char a; // expected-note {{previous declaration is here}}
char a; // expected-error {{duplicate member 'a'}}
};
struct s0 f0(void) {}
// <rdar://problem/8177927> - This previously triggered an assertion failure.
struct x0 {
unsigned int x1;
};
// rdar://problem/9150338
static struct test1 { // expected-warning {{'static' ignored on this declaration}}
int x;
};
const struct test2 { // expected-warning {{'const' ignored on this declaration}}
int x;
};
inline struct test3 { // expected-error {{'inline' can only appear on functions}}
int x;
};
struct hiding_1 {};
struct hiding_2 {};
void test_hiding() {
struct hiding_1 *hiding_1();
extern struct hiding_2 *hiding_2;
struct hiding_1 *p = hiding_1();
struct hiding_2 *q = hiding_2;
}
struct PreserveAttributes {};
typedef struct __attribute__((noreturn)) PreserveAttributes PreserveAttributes_t; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
// PR46255
struct FlexibleArrayMem {
int a;
int b[];
};
struct FollowedByNamed {
struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
int i;
};
struct FollowedByUnNamed {
struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
struct {
int i;
};
};
struct InAnonymous {
struct { // expected-warning-re {{field '' with variable sized type 'struct InAnonymous::(anonymous at {{.+}})' not at the end of a struct or class is a GNU extension}}
struct FlexibleArrayMem a;
};
int i;
};
struct InAnonymousFollowedByAnon {
struct { // expected-warning-re {{field '' with variable sized type 'struct InAnonymousFollowedByAnon::(anonymous at {{.+}})' not at the end of a struct or class is a GNU extension}}
struct FlexibleArrayMem a;
};
struct {
int i;
};
};
// This is the behavior in C++ as well, so making sure we reproduce it here.
struct InAnonymousFollowedByEmpty {
struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
struct {};
};