]> granicus.if.org Git - clang/commitdiff
Make sure that out-of-line function and variable definitions are not
authorDouglas Gregor <dgregor@apple.com>
Mon, 28 Sep 2009 18:41:37 +0000 (18:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 28 Sep 2009 18:41:37 +0000 (18:41 +0000)
pushed into scope. Fixes PR5056.

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

lib/Sema/SemaDecl.cpp
test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp [new file with mode: 0644]

index d0463c658ea3fad0643162995ba08325f6bbc832..7f3f24efeadcd085af0ff5473135da21ac371a65 100644 (file)
@@ -288,14 +288,22 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
          ((DeclContext *)S->getEntity())->isTransparentContext())
     S = S->getParent();
 
-  S->AddDecl(DeclPtrTy::make(D));
-
   // Add scoped declarations into their context, so that they can be
   // found later. Declarations without a context won't be inserted
   // into any context.
   if (AddToContext)
     CurContext->addDecl(D);
 
+  // Out-of-line function and variable definitions should not be pushed into
+  // scope.
+  if ((isa<FunctionTemplateDecl>(D) &&
+       cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->isOutOfLine()) ||
+      (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isOutOfLine()) ||
+      (isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine()))
+    return;
+
+  S->AddDecl(DeclPtrTy::make(D));
+  
   // C++ [basic.scope]p4:
   //   -- exactly one declaration shall declare a class name or
   //   enumeration name that is not a typedef name and the other
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp
new file mode 100644 (file)
index 0000000..602fd37
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+extern "C" void * malloc(int);
+
+template <typename T> struct A {
+  void *malloc(int);
+};
+
+template <typename T>
+inline void *A<T>::malloc(int)
+{
+  return 0;
+}
+
+void f() {
+  malloc(10);
+}