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