]> granicus.if.org Git - clang/commitdiff
PR36157: When injecting an implicit function declaration in C89, find the right
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 1 Feb 2018 20:01:49 +0000 (20:01 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 1 Feb 2018 20:01:49 +0000 (20:01 +0000)
DeclContext rather than injecting it wherever we happen to be.

This avoids creating functions whose DeclContext is a struct or similar.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@323998 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/Sema/bitfield.c
test/Sema/cxx-as-c.c [new file with mode: 0644]

index 1a7d9a84306f7dcb106a2eec35b3df943971e530..526f6802c330c9f5d9ae17248621f6b51bb942f3 100644 (file)
@@ -12910,10 +12910,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,
 /// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
 NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
                                           IdentifierInfo &II, Scope *S) {
+  // Find the scope in which the identifier is injected and the corresponding
+  // DeclContext.
+  // FIXME: C89 does not say what happens if there is no enclosing block scope.
+  // In that case, we inject the declaration into the translation unit scope
+  // instead.
   Scope *BlockScope = S;
   while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent())
     BlockScope = BlockScope->getParent();
 
+  Scope *ContextScope = BlockScope;
+  while (!ContextScope->getEntity())
+    ContextScope = ContextScope->getParent();
+  ContextRAII SavedContext(*this, ContextScope->getEntity());
+
   // Before we produce a declaration for an implicitly defined
   // function, see whether there was a locally-scoped declaration of
   // this name as a function or variable. If so, use that
index d625366e4e1f26b71f16bcef42758ff754a27033..13e9480a378bede178eb947cdd615681b07afce4 100644 (file)
@@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act like compound-assignment.
 struct Test6 {
   : 0.0; // expected-error{{type name requires a specifier or qualifier}}
 };
+
+struct PR36157 {
+  int n : 1 ? 1 : implicitly_declare_function(); // expected-warning {{invalid in C99}}
+};
diff --git a/test/Sema/cxx-as-c.c b/test/Sema/cxx-as-c.c
new file mode 100644 (file)
index 0000000..41d7350
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify
+
+// PR36157
+struct Foo {
+  Foo(int n) : n_(n) {} // expected-error 1+{{}} expected-warning 1+{{}}
+private:
+  int n;
+};
+int main() { Foo f; } // expected-error 1+{{}}