зеркало из https://github.com/microsoft/clang-1.git
fix PR8217, a silent miscompilation of invalid code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116166 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
9046c224f1
Коммит
16c5dea6c2
|
@ -2876,12 +2876,12 @@ public:
|
|||
|
||||
unsigned getNumInits() const { return InitExprs.size(); }
|
||||
|
||||
const Expr* getInit(unsigned Init) const {
|
||||
const Expr *getInit(unsigned Init) const {
|
||||
assert(Init < getNumInits() && "Initializer access out of range!");
|
||||
return cast_or_null<Expr>(InitExprs[Init]);
|
||||
}
|
||||
|
||||
Expr* getInit(unsigned Init) {
|
||||
Expr *getInit(unsigned Init) {
|
||||
assert(Init < getNumInits() && "Initializer access out of range!");
|
||||
return cast_or_null<Expr>(InitExprs[Init]);
|
||||
}
|
||||
|
|
|
@ -2152,6 +2152,8 @@ def err_member_def_does_not_match : Error<
|
|||
"out-of-line definition of %0 does not match any declaration in %1">;
|
||||
def err_nonstatic_member_out_of_line : Error<
|
||||
"non-static data member defined out-of-line">;
|
||||
def err_nonstatic_flexible_variable : Error<
|
||||
"non-static initialization of a variable with flexible array member">;
|
||||
def err_qualified_typedef_declarator : Error<
|
||||
"typedef declarator cannot be qualified">;
|
||||
def err_qualified_param_declarator : Error<
|
||||
|
|
|
@ -1591,7 +1591,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
|||
/// no declarator (e.g. "struct foo;") is parsed.
|
||||
Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
|
||||
DeclSpec &DS) {
|
||||
// FIXME: Error on auto/register at file scope
|
||||
// FIXME: Error on inline/virtual/explicit
|
||||
// FIXME: Warn on useless __thread
|
||||
// FIXME: Warn on useless const/volatile
|
||||
|
@ -2686,7 +2685,7 @@ static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) {
|
|||
}
|
||||
|
||||
NamedDecl*
|
||||
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
QualType R, TypeSourceInfo *TInfo,
|
||||
LookupResult &Previous,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
|
@ -2821,7 +2820,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
ProcessDeclAttributes(S, NewVD, D);
|
||||
|
||||
// Handle GNU asm-label extension (encoded as an attribute).
|
||||
if (Expr *E = (Expr*) D.getAsmLabel()) {
|
||||
if (Expr *E = (Expr*)D.getAsmLabel()) {
|
||||
// The parser guarantees this is a string.
|
||||
StringLiteral *SE = cast<StringLiteral>(E);
|
||||
NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
|
||||
|
@ -2991,7 +2990,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
|
|||
// This includes arrays of objects with address space qualifiers, but not
|
||||
// automatic variables that point to other address spaces.
|
||||
// ISO/IEC TR 18037 S5.1.2
|
||||
if (NewVD->hasLocalStorage() && (T.getAddressSpace() != 0)) {
|
||||
if (NewVD->hasLocalStorage() && T.getAddressSpace() != 0) {
|
||||
Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
|
||||
return NewVD->setInvalidDecl();
|
||||
}
|
||||
|
@ -2999,7 +2998,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
|
|||
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
|
||||
&& !NewVD->hasAttr<BlocksAttr>())
|
||||
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
|
||||
|
||||
|
||||
bool isVM = T->isVariablyModifiedType();
|
||||
if (isVM || NewVD->hasAttr<CleanupAttr>() ||
|
||||
NewVD->hasAttr<BlocksAttr>())
|
||||
|
@ -4326,6 +4325,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
|||
Init->setType(DclT);
|
||||
}
|
||||
|
||||
|
||||
// If this variable is a local declaration with record type, make sure it
|
||||
// doesn't have a flexible member initialization. We only support this as a
|
||||
// global/static definition.
|
||||
if (VDecl->hasLocalStorage())
|
||||
if (const RecordType *RT = VDecl->getType()->getAs<RecordType>())
|
||||
if (RT->getDecl()->hasFlexibleArrayMember() && isa<InitListExpr>(Init)) {
|
||||
Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
|
||||
VDecl->setInvalidDecl();
|
||||
}
|
||||
|
||||
// Check any implicit conversions within the expression.
|
||||
CheckImplicitConversions(Init, VDecl->getLocation());
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ struct one {
|
|||
struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}}
|
||||
|
||||
void test() {
|
||||
struct one x3 = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
|
||||
struct one x3 = {5, {1, 2, 3}}; // \
|
||||
// expected-warning{{flexible array initialization is a GNU extension}} \
|
||||
// expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
}
|
||||
|
||||
struct foo {
|
||||
|
@ -56,3 +58,18 @@ struct Y {
|
|||
int e;
|
||||
struct X xs[]; // expected-warning{{'struct X' may not be used as an array element due to flexible array member}}
|
||||
};
|
||||
|
||||
|
||||
// PR8217
|
||||
struct PR8217a {
|
||||
int i;
|
||||
char v[];
|
||||
};
|
||||
|
||||
void PR8217() {
|
||||
struct PR8217a foo1 = { .i = 0, .v = "foo" }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a foo2 = { .i = 0 }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a foo3 = { .i = 0, .v = { 'b', 'a', 'r', '\0' } }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a bar;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,3 +143,4 @@ int PR4386_a = ((void *) PR4386_bar) != 0;
|
|||
int PR4386_b = ((void *) PR4386_foo) != 0; // expected-error{{initializer element is not a compile-time constant}}
|
||||
int PR4386_c = ((void *) PR4386_zed) != 0;
|
||||
int PR4386_zed() __attribute((weak));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче