Index: include/clang/Sema/Scope.h =================================================================== --- include/clang/Sema/Scope.h +++ include/clang/Sema/Scope.h @@ -124,6 +124,9 @@ /// We are currently in the filter expression of an SEH except block. SEHFilterScope = 0x200000, + + /// This is a compound statement scope. + CompoundStmtScope = 0x400000, }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -429,6 +432,9 @@ /// \brief Determine whether this scope is a SEH '__except' block. bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; } + /// \brief Determine whether this scope is a compound statement scope. + bool isCompoundStmtScope() const { return getFlags() & Scope::CompoundStmtScope; } + /// \brief Returns if rhs has a higher scope depth than this. /// /// The caller is responsible for calling this only if one of the two scopes Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -840,7 +840,8 @@ } StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { - return ParseCompoundStatement(isStmtExpr, Scope::DeclScope); + return ParseCompoundStatement(isStmtExpr, + Scope::DeclScope | Scope::CompoundStmtScope); } /// ParseCompoundStatement - Parse a "{}" block. Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12605,12 +12605,16 @@ SourceLocation()); D.SetIdentifier(&II, Loc); - // Insert this function into translation-unit scope. + // Insert this function into the enclosing block scope. + while (S && !S->isCompoundStmtScope() && !S->isFunctionScope()) + S = S->getParent(); + if (S == nullptr) + S = TUScope; DeclContext *PrevDC = CurContext; CurContext = Context.getTranslationUnitDecl(); - FunctionDecl *FD = cast(ActOnDeclarator(TUScope, D)); + FunctionDecl *FD = cast(ActOnDeclarator(S, D)); FD->setImplicit(); CurContext = PrevDC; Index: test/Sema/implicit-decl-c90.c =================================================================== --- /dev/null +++ test/Sema/implicit-decl-c90.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -std=c90 -verify -fsyntax-only +void t0(int x) { + int (*p)(); + if(x > 0) + x = g() + 1; + p = g; + if(x < 0) { + extern void u(int (*)[h()]); + int (*q)() = h; + } + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ +} + +void t1(int x) { + int (*p)(); + switch (x) { + g(); + case 0: + x = h() + 1; + break; + case 1: + p = g; + p = h; + break; + } + p = g; /* expected-error {{use of undeclared identifier 'g'}} */ + p = h; /* expected-error {{use of undeclared identifier 'h'}} */ +} + +int (*p)() = g; /* expected-error {{use of undeclared identifier 'g'}} */ +int (*q)() = h; /* expected-error {{use of undeclared identifier 'h'}} */ + +float g(); /* not expecting conflicting types diagnostics here */ Index: test/Sema/implicit-decl.c =================================================================== --- test/Sema/implicit-decl.c +++ test/Sema/implicit-decl.c @@ -9,8 +9,7 @@ int32_t *vector[16]; const char compDesc[16 + 1]; int32_t compCount = 0; - if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \ - expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} + if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-error {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}} } printg("Hello, World!\n"); // expected-error{{implicit declaration of function 'printg' is invalid in C99}} \ @@ -18,7 +17,7 @@ __builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}} } -Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}} +Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { return 0; }