]> granicus.if.org Git - clang/commitdiff
When resolving the address of an overloaded function or function template, mark the...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 17 Oct 2009 21:12:09 +0000 (21:12 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 17 Oct 2009 21:12:09 +0000 (21:12 +0000)
The most important effect of this is that function templates only referenced by address expressions now get instantiated. This, in turn, means that Hello World compiles with the Apache stdcxx library even when using endl.

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

lib/Sema/SemaOverload.cpp
test/CodeGenCXX/address-of-fntemplate.cpp

index 5f874e8dbc95d9c868e2c3ba7052773753640976..0f2256b6bcc31a670d141e8d47c471869aeaca6c 100644 (file)
@@ -4334,8 +4334,11 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
   // If there were 0 or 1 matches, we're done.
   if (Matches.empty())
     return 0;
-  else if (Matches.size() == 1)
-    return *Matches.begin();
+  else if (Matches.size() == 1) {
+    FunctionDecl *Result = *Matches.begin();
+    MarkDeclarationReferenced(From->getLocStart(), Result);
+    return Result;
+  }
 
   // C++ [over.over]p4:
   //   If more than one function is selected, [...]
@@ -4351,14 +4354,17 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
     // two-pass algorithm (similar to the one used to identify the
     // best viable function in an overload set) that identifies the
     // best function template (if it exists).
-    llvm::SmallVector<FunctionDecl *, 8> TemplateMatches(Matches.begin(), 
+    llvm::SmallVector<FunctionDecl *, 8> TemplateMatches(Matches.begin(),
                                                          Matches.end());
-    return getMostSpecialized(TemplateMatches.data(), TemplateMatches.size(), 
-                              TPOC_Other, From->getLocStart(),
-                              PDiag(),
-                              PDiag(diag::err_addr_ovl_ambiguous)
-                              << TemplateMatches[0]->getDeclName(), 
-                              PDiag(diag::err_ovl_template_candidate));
+    FunctionDecl *Result =
+        getMostSpecialized(TemplateMatches.data(), TemplateMatches.size(),
+                           TPOC_Other, From->getLocStart(),
+                           PDiag(),
+                           PDiag(diag::err_addr_ovl_ambiguous)
+                               << TemplateMatches[0]->getDeclName(),
+                           PDiag(diag::err_ovl_template_candidate));
+    MarkDeclarationReferenced(From->getLocStart(), Result);
+    return Result;
   }
 
   //   [...] any function template specializations in the set are
@@ -4370,8 +4376,11 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
   
   // [...] After such eliminations, if any, there shall remain exactly one
   // selected function.
-  if (RemainingMatches.size() == 1)
-    return RemainingMatches.front();
+  if (RemainingMatches.size() == 1) {
+    FunctionDecl *Result = RemainingMatches.front();
+    MarkDeclarationReferenced(From->getLocStart(), Result);
+    return Result;
+  }
 
   // FIXME: We should probably return the same thing that BestViableFunction
   // returns (even if we issue the diagnostics here).
index cbf042551deb9ed8b956110aad1af46133dae8f3..9a1364325f74f1c249ac0507156c94e6d480f67b 100644 (file)
@@ -2,8 +2,7 @@
 template <typename T> void f(T) {}
 
 void test() {
-  // FIXME: This emits only a declaration instead of a definition
   // CHECK: @_Z1fIiEvT_
   void (*p)(int) = &f;
 }
-// CHECK-disabled: define linkonce_odr void @_Z1fIiEvT_
+// CHECK: define linkonce_odr void @_Z1fIiEvT_