<div dir="ltr">Ok.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 29, 2014 at 2:35 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Tue, Jul 29, 2014 at 11:44 AM, Larisse Voufo <span dir="ltr"><<a href="mailto:lvoufo@google.com" target="_blank">lvoufo@google.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: lvoufo<br>
Date: Tue Jul 29 13:44:19 2014<br>
New Revision: 214192<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=214192&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=214192&view=rev</a><br>
Log:<br>
Fix PR10177 where non-type template arguments to alias templates are not marked as used in dependent contexts. The fix actually forces non-dependent names to be checked at template definition time as expected from the standard.<br>



<br>
Modified:<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/test/SemaCXX/PR10177.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=214192&r1=214191&r2=214192&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=214192&r1=214191&r2=214192&view=diff</a><br>



==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jul 29 13:44:19 2014<br>
@@ -12439,6 +12439,8 @@ static void DoMarkVarDeclReferenced(Sema<br>
          "Invalid Expr argument to DoMarkVarDeclReferenced");<br>
   Var->setReferenced();<br>
<br>
+  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();<br>
+<br>
   // If the context is not potentially evaluated, this is not an odr-use and<br>
   // does not trigger instantiation.<br>
   if (!IsPotentiallyEvaluatedContext(SemaRef)) {<br>
@@ -12453,25 +12455,26 @@ static void DoMarkVarDeclReferenced(Sema<br>
     // arguments, where local variables can't be used.<br>
     const bool RefersToEnclosingScope =<br>
         (SemaRef.CurContext != Var->getDeclContext() &&<br>
-         Var->getDeclContext()->isFunctionOrMethod() &&<br>
-         Var->hasLocalStorage());<br>
-    if (!RefersToEnclosingScope)<br>
-      return;<br>
-<br>
-    if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {<br>
-      // If a variable could potentially be odr-used, defer marking it so<br>
-      // until we finish analyzing the full expression for any lvalue-to-rvalue<br>
-      // or discarded value conversions that would obviate odr-use.<br>
-      // Add it to the list of potential captures that will be analyzed<br>
-      // later (ActOnFinishFullExpr) for eventual capture and odr-use marking<br>
-      // unless the variable is a reference that was initialized by a constant<br>
-      // expression (this will never need to be captured or odr-used).<br>
-      assert(E && "Capture variable should be used in an expression.");<br>
-      if (!Var->getType()->isReferenceType() ||<br>
-          !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))<br>
-        LSI->addPotentialCapture(E->IgnoreParens());<br>
+         Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());<br>
+    if (RefersToEnclosingScope) {<br>
+      if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {<br>
+        // If a variable could potentially be odr-used, defer marking it so<br>
+        // until we finish analyzing the full expression for any<br>
+        // lvalue-to-rvalue<br>
+        // or discarded value conversions that would obviate odr-use.<br>
+        // Add it to the list of potential captures that will be analyzed<br>
+        // later (ActOnFinishFullExpr) for eventual capture and odr-use marking<br>
+        // unless the variable is a reference that was initialized by a constant<br>
+        // expression (this will never need to be captured or odr-used).<br>
+        assert(E && "Capture variable should be used in an expression.");<br>
+        if (!Var->getType()->isReferenceType() ||<br>
+            !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))<br>
+          LSI->addPotentialCapture(E->IgnoreParens());<br>
+      }<br>
     }<br>
-    return;<br>
+<br>
+    if (!isTemplateInstantiation(TSK))<br>
+       return;<br></blockquote><div><br></div></div></div><div>Should we really mark the variable as odr-used in this case but not for non-template-instantiations? That inconsistency doesn't seem right to me. I think the right behavior here is to *only* perform the instantiation and to skip the marking as odr-used. In particular, for a case like:</div>


<div><br></div><div>  namespace { template<typename> extern int n; }</div><div>  template<typename T> int g() { return n<int>; }<br></div><div><br></div><div>... we should *not* produce a "variable '(anonymous namespace)::n<int>' has internal linkage but is not defined" warning.</div>

<div><div class="h5">
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
   }<br>
<br>
   VarTemplateSpecializationDecl *VarSpec =<br>
@@ -12483,7 +12486,6 @@ static void DoMarkVarDeclReferenced(Sema<br>
   // templates of class templates, and variable template specializations. Delay<br>
   // instantiations of variable templates, except for those that could be used<br>
   // in a constant expression.<br>
-  TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();<br>
   if (isTemplateInstantiation(TSK)) {<br>
     bool TryInstantiating = TSK == TSK_ImplicitInstantiation;<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/PR10177.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR10177.cpp?rev=214192&r1=214191&r2=214192&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR10177.cpp?rev=214192&r1=214191&r2=214192&view=diff</a><br>



==============================================================================<br>
--- cfe/trunk/test/SemaCXX/PR10177.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/PR10177.cpp Tue Jul 29 13:44:19 2014<br>
@@ -9,22 +9,28 @@ struct U {<br>
   static int a;<br>
 };<br>
<br>
-template<int N> struct S; // expected-note 2{{here}}<br>
+template<int N> struct S; // expected-note 6{{here}}<br>
<br>
 template<int N><br>
-int U<N>::a = S<N>::kError; // expected-error 2{{undefined}}<br>
+int U<N>::a = S<N>::kError; // expected-error 6{{undefined}}<br>
<br>
 template<typename T><br>
 void f() {<br>
-  // FIXME: The standard suggests that U<0>::a is odr-used by this expression,<br>
-  // but it's not entirely clear that's the right behaviour.<br>
-  (void)alias_ref<int, int&, U<0>::a>();<br>
+  (void)alias_ref<int, int&, U<0>::a>(); // expected-note {{here}}<br>
   (void)func_ref<int, int&, U<1>::a>(); // expected-note {{here}}<br>
   (void)class_ref<int, int&, U<2>::a>(); // expected-note {{here}}<br>
 };<br>
<br>
+template<int N><br>
+void fi() {<br>
+  (void)alias_ref<int, int&, U<N>::a>(); // expected-note {{here}}<br>
+  (void)func_ref<int, int&, U<N+1>::a>(); // expected-note {{here}}<br>
+  (void)class_ref<int, int&, U<N+2>::a>(); // expected-note {{here}}<br>
+};<br>
+<br>
 int main() {<br>
-  f<int>(); // expected-note 2{{here}}<br>
+  f<int>();   // NOTE: Non-dependent name uses are type-checked at template definition time.<br>
+  fi<10>();   // expected-note 3{{here}}<br>
 }<br>
<br>
 namespace N {<br>
@@ -38,3 +44,4 @@ namespace N {<br>
   }<br>
   int j = f<int>();<br>
 }<br>
+<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>