[cfe-commits] r84362 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp test/CodeGenCXX/address-of-fntemplate.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Sat Oct 17 13:50:27 PDT 2009
Author: cornedbee
Date: Sat Oct 17 15:50:27 2009
New Revision: 84362
URL: http://llvm.org/viewvc/llvm-project?rev=84362&view=rev
Log:
Don't add implicit casts of explicit address-taking of overloaded functions.
Taking the address of an overloaded function with an explicit address-of operator wrapped the operator in an implicit cast that added yet another pointer level, leaving us with a corrupted AST, which crashed CodeGen in the test case I've added. Fix this by making FixOverloadedFunctionReference return whether there was an address-of operator and not adding the implicit cast in that case.
Added:
cfe/trunk/test/CodeGenCXX/address-of-fntemplate.cpp
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=84362&r1=84361&r2=84362&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Oct 17 15:50:27 2009
@@ -929,7 +929,7 @@
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain);
- void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
+ bool FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
void AddOverloadedCallCandidates(NamedDecl *Callee,
DeclarationName &UnqualifiedName,
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=84362&r1=84361&r2=84362&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Oct 17 15:50:27 2009
@@ -1222,8 +1222,13 @@
if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
return true;
- FixOverloadedFunctionReference(From, Fn);
+ bool WasAddrOf = FixOverloadedFunctionReference(From, Fn);
FromType = From->getType();
+ // If there's already an address-of operator in the expression, we have
+ // the right type already, and the code below would just introduce an
+ // invalid additional pointer level.
+ if (WasAddrOf)
+ break;
}
FromType = Context.getPointerType(FromType);
ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=84362&r1=84361&r2=84362&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Oct 17 15:50:27 2009
@@ -5300,10 +5300,12 @@
/// perhaps a '&' around it). We have resolved the overloaded function
/// to the function declaration Fn, so patch up the expression E to
/// refer (possibly indirectly) to Fn.
-void Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
+/// Returns true if the function reference used an explicit address-of operator.
+bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
+ bool ret = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
E->setType(PE->getSubExpr()->getType());
+ return ret;
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
"Can only take the address of an overloaded function");
@@ -5322,11 +5324,12 @@
= Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
E->setType(Context.getMemberPointerType(Fn->getType(),
ClassType.getTypePtr()));
- return;
+ return true;
}
}
FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
E->setType(Context.getPointerType(UnOp->getSubExpr()->getType()));
+ return true;
} else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
isa<FunctionTemplateDecl>(DR->getDecl())) &&
@@ -5339,6 +5342,7 @@
} else {
assert(false && "Invalid reference to overloaded function");
}
+ return false;
}
} // end namespace clang
Added: cfe/trunk/test/CodeGenCXX/address-of-fntemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/address-of-fntemplate.cpp?rev=84362&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/address-of-fntemplate.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/address-of-fntemplate.cpp Sat Oct 17 15:50:27 2009
@@ -0,0 +1,9 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+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_
More information about the cfe-commits
mailing list