r194775 - PR17533 and duplicates: don't compute the return type of an overloaded operator

Richard Smith richard-llvm at metafoo.co.uk
Thu Nov 14 18:58:23 PST 2013


Author: rsmith
Date: Thu Nov 14 20:58:23 2013
New Revision: 194775

URL: http://llvm.org/viewvc/llvm-project?rev=194775&view=rev
Log:
PR17533 and duplicates: don't compute the return type of an overloaded operator
until after we've referenced the operator; otherwise, we might pick up a
not-yet-deduced type.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=194775&r1=194774&r2=194775&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Nov 14 20:58:23 2013
@@ -6737,12 +6737,16 @@ Sema::ActOnFunctionDeclarator(Scope *S,
         Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);
     }
 
-    if (getLangOpts().CPlusPlus1y && NewFD->isDependentContext() &&
+    if (getLangOpts().CPlusPlus1y &&
+        (NewFD->isDependentContext() ||
+         (isFriend && CurContext->isDependentContext())) &&
         NewFD->getResultType()->isUndeducedType()) {
       // If the function template is referenced directly (for instance, as a
       // member of the current instantiation), pretend it has a dependent type.
       // This is not really justified by the standard, but is the only sane
       // thing to do.
+      // FIXME: For a friend function, we have not marked the function as being
+      // a friend yet, so 'isDependentContext' on the FD doesn't work.
       const FunctionProtoType *FPT =
           NewFD->getType()->castAs<FunctionProtoType>();
       QualType Result = SubstAutoType(FPT->getResultType(),

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=194775&r1=194774&r2=194775&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Nov 14 20:58:23 2013
@@ -10523,17 +10523,17 @@ Sema::CreateOverloadedUnaryOp(SourceLoca
         Input = InputInit.take();
       }
 
-      // Determine the result type.
-      QualType ResultTy = FnDecl->getResultType();
-      ExprValueKind VK = Expr::getValueKindForType(ResultTy);
-      ResultTy = ResultTy.getNonLValueExprType(Context);
-
       // Build the actual expression node.
       ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl,
                                                 HadMultipleCandidates, OpLoc);
       if (FnExpr.isInvalid())
         return ExprError();
 
+      // Determine the result type.
+      QualType ResultTy = FnDecl->getResultType();
+      ExprValueKind VK = Expr::getValueKindForType(ResultTy);
+      ResultTy = ResultTy.getNonLValueExprType(Context);
+
       Args[0] = Input;
       CallExpr *TheCall =
         new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray,
@@ -10757,11 +10757,6 @@ Sema::CreateOverloadedBinOp(SourceLocati
           Args[1] = RHS = Arg1.takeAs<Expr>();
         }
 
-        // Determine the result type.
-        QualType ResultTy = FnDecl->getResultType();
-        ExprValueKind VK = Expr::getValueKindForType(ResultTy);
-        ResultTy = ResultTy.getNonLValueExprType(Context);
-
         // Build the actual expression node.
         ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
                                                   Best->FoundDecl,
@@ -10769,6 +10764,11 @@ Sema::CreateOverloadedBinOp(SourceLocati
         if (FnExpr.isInvalid())
           return ExprError();
 
+        // Determine the result type.
+        QualType ResultTy = FnDecl->getResultType();
+        ExprValueKind VK = Expr::getValueKindForType(ResultTy);
+        ResultTy = ResultTy.getNonLValueExprType(Context);
+
         CXXOperatorCallExpr *TheCall =
           new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
                                             Args, ResultTy, VK, OpLoc,
@@ -10969,11 +10969,6 @@ Sema::CreateOverloadedArraySubscriptExpr
 
         Args[1] = InputInit.takeAs<Expr>();
 
-        // Determine the result type
-        QualType ResultTy = FnDecl->getResultType();
-        ExprValueKind VK = Expr::getValueKindForType(ResultTy);
-        ResultTy = ResultTy.getNonLValueExprType(Context);
-
         // Build the actual expression node.
         DeclarationNameInfo OpLocInfo(OpName, LLoc);
         OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
@@ -10985,6 +10980,11 @@ Sema::CreateOverloadedArraySubscriptExpr
         if (FnExpr.isInvalid())
           return ExprError();
 
+        // Determine the result type
+        QualType ResultTy = FnDecl->getResultType();
+        ExprValueKind VK = Expr::getValueKindForType(ResultTy);
+        ResultTy = ResultTy.getNonLValueExprType(Context);
+
         CXXOperatorCallExpr *TheCall =
           new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
                                             FnExpr.take(), Args,

Modified: cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp?rev=194775&r1=194774&r2=194775&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp Thu Nov 14 20:58:23 2013
@@ -457,3 +457,22 @@ void bar() { puts("bar"); }
 int main() { return foo(0); }
 
 }
+
+namespace OverloadedOperators {
+  template<typename T> struct A {
+    auto operator()() { return T{}; }
+    auto operator[](int) { return T{}; }
+    auto operator+(int) { return T{}; }
+    auto operator+() { return T{}; }
+    friend auto operator-(A) { return T{}; }
+    friend auto operator-(A, A) { return T{}; }
+  };
+  void f(A<int> a) {
+    int b = a();
+    int c = a[0];
+    int d = a + 0;
+    int e = +a;
+    int f = -a;
+    int g = a - a;
+  }
+}





More information about the cfe-commits mailing list