[cfe-commits] r101549 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaChecking.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaInit.h lib/Sema/SemaStmt.cpp test/SemaTemplate/instantiate-expr-2.cpp
Douglas Gregor
dgregor at apple.com
Fri Apr 16 15:09:46 PDT 2010
Author: dgregor
Date: Fri Apr 16 17:09:46 2010
New Revision: 101549
URL: http://llvm.org/viewvc/llvm-project?rev=101549&view=rev
Log:
Collapse the three separate initialization paths in
TryStaticImplicitCast (for references, class types, and everything
else, respectively) into a single invocation of
InitializationSequence.
One of the paths (for class types) was the only client of
Sema::TryInitializationByConstructor, which I have eliminated. This
also simplified the interface for much of the cast-checking logic,
eliminating yet more code.
I've kept the representation of C++ functional casts with <> 1
arguments the same, despite the fact that I hate it. That fix will
come soon. To satisfy my paranoia, I've bootstrapped + tested Clang
with these changes.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCXXCast.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaInit.h
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Apr 16 17:09:46 2010
@@ -2161,12 +2161,6 @@
/// it simply returns the passed in expression.
OwningExprResult MaybeBindToTemporary(Expr *E);
- CXXConstructorDecl *
- TryInitializationByConstructor(QualType ClassType,
- Expr **Args, unsigned NumArgs,
- SourceLocation Loc,
- InitializationKind Kind);
-
bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
MultiExprArg ArgsPtr,
SourceLocation Loc,
@@ -4206,7 +4200,6 @@
/// C semantics, or forward to CXXCheckCStyleCast in C++.
bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
CastExpr::CastKind &Kind,
- CXXMethodDecl *& ConversionDecl,
bool FunctionalStyle = false);
// CheckVectorCast - check type constraints for vectors.
@@ -4227,8 +4220,7 @@
/// CXXCheckCStyleCast - Check constraints of a C-style or function-style
/// cast under C++ semantics.
bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind, bool FunctionalStyle,
- CXXMethodDecl *&ConversionDecl);
+ CastExpr::CastKind &Kind, bool FunctionalStyle);
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Fri Apr 16 17:09:46 2010
@@ -46,8 +46,7 @@
CastExpr::CastKind &Kind);
static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
- CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl);
+ CastExpr::CastKind &Kind);
static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
const SourceRange &DestRange,
@@ -94,14 +93,12 @@
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl);
+ CastExpr::CastKind &Kind);
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl);
+ CastExpr::CastKind &Kind);
static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, unsigned &msg);
static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
@@ -168,21 +165,8 @@
}
case tok::kw_static_cast: {
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- if (!TypeDependent) {
- CXXMethodDecl *Method = 0;
-
- CheckStaticCast(*this, Ex, DestType, OpRange, Kind, Method);
-
- if (Method) {
- OwningExprResult CastArg
- = BuildCXXCastArgument(OpLoc, DestType.getNonReferenceType(),
- Kind, Method, Owned(Ex));
- if (CastArg.isInvalid())
- return ExprError();
-
- Ex = CastArg.takeAs<Expr>();
- }
- }
+ if (!TypeDependent)
+ CheckStaticCast(*this, Ex, DestType, OpRange, Kind);
return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
Kind, Ex, DestTInfo, OpLoc));
@@ -447,8 +431,7 @@
/// implicit conversions explicit and getting rid of data loss warnings.
void
CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
- const SourceRange &OpRange, CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl) {
+ const SourceRange &OpRange, CastExpr::CastKind &Kind) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -462,7 +445,7 @@
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, msg,
- Kind, ConversionDecl)
+ Kind)
!= TC_Success && msg != 0)
Self.Diag(OpRange.getBegin(), msg) << CT_Static
<< SrcExpr->getType() << DestType << OpRange;
@@ -474,8 +457,7 @@
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange, unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl) {
+ CastExpr::CastKind &Kind) {
// The order the tests is not entirely arbitrary. There is one conversion
// that can be handled in two different ways. Given:
// struct A {};
@@ -512,7 +494,7 @@
// C++ 5.2.9p2: An expression e can be explicitly converted to a type T
// [...] if the declaration "T t(e);" is well-formed, [...].
tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg,
- Kind, ConversionDecl);
+ Kind);
if (tcr != TC_NotApplicable)
return tcr;
@@ -900,8 +882,7 @@
TryCastResult
TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
bool CStyle, const SourceRange &OpRange, unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXMethodDecl *&ConversionDecl) {
+ CastExpr::CastKind &Kind) {
if (DestType->isRecordType()) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
diag::err_bad_dynamic_cast_incomplete)) {
@@ -909,66 +890,33 @@
return TC_Failed;
}
}
-
- if (DestType->isReferenceType()) {
- // All reference bindings insert implicit casts above that do the actual
- // casting.
- Kind = CastExpr::CK_NoOp;
-
- // At this point of CheckStaticCast, if the destination is a reference,
- // this has to work. There is no other way that works.
- // On the other hand, if we're checking a C-style cast, we've still got
- // the reinterpret_cast way.
- InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
- InitializationKind InitKind = InitializationKind::CreateCast(OpRange,
- CStyle);
- InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
- if (InitSeq.getKind() == InitializationSequence::FailedSequence && CStyle)
- return TC_NotApplicable;
-
- Sema::OwningExprResult Result
- = InitSeq.Perform(Self, Entity, InitKind,
- Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
- if (Result.isInvalid()) {
- msg = 0;
- return TC_Failed;
- }
-
- SrcExpr = Result.takeAs<Expr>();
- return TC_Success;
- }
-
- if (DestType->isRecordType()) {
- if (CXXConstructorDecl *Constructor
- = Self.TryInitializationByConstructor(DestType, &SrcExpr, 1,
- OpRange.getBegin(),
- InitializationKind::CreateDirect(OpRange.getBegin(),
- OpRange.getBegin(),
- OpRange.getEnd()))) {
- ConversionDecl = Constructor;
- Kind = CastExpr::CK_ConstructorConversion;
- return TC_Success;
- }
-
- return TC_NotApplicable;
- }
-
+
+ // At this point of CheckStaticCast, if the destination is a reference,
+ // this has to work. There is no other way that works.
+ // On the other hand, if we're checking a C-style cast, we've still got
+ // the reinterpret_cast way.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
InitializationKind InitKind
- = InitializationKind::CreateCast(/*FIXME:*/OpRange, CStyle);
+ = InitializationKind::CreateCast(/*FIXME:*/OpRange,
+ CStyle);
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
- if (InitSeq.getKind() == InitializationSequence::FailedSequence)
+ if (InitSeq.getKind() == InitializationSequence::FailedSequence &&
+ (CStyle || !DestType->isReferenceType()))
return TC_NotApplicable;
-
+
Sema::OwningExprResult Result
- = InitSeq.Perform(Self, Entity, InitKind,
- Action::MultiExprArg(Self, (void **)&SrcExpr, 1));
- Kind = CastExpr::CK_NoOp;
+ = InitSeq.Perform(Self, Entity, InitKind,
+ Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
if (Result.isInvalid()) {
msg = 0;
return TC_Failed;
}
+ if (InitSeq.isConstructorInitialization())
+ Kind = CastExpr::CK_ConstructorConversion;
+ else
+ Kind = CastExpr::CK_NoOp;
+
SrcExpr = Result.takeAs<Expr>();
return TC_Success;
}
@@ -1234,8 +1182,7 @@
}
bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind, bool FunctionalStyle,
- CXXMethodDecl *&ConversionDecl) {
+ CastExpr::CastKind &Kind, bool FunctionalStyle) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -1270,8 +1217,7 @@
if (tcr == TC_NotApplicable) {
// ... or if that is not possible, a static_cast, ignoring const, ...
- tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg,
- Kind, ConversionDecl);
+ tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg, Kind);
if (tcr == TC_NotApplicable) {
// ... and finally a reinterpret_cast, ignoring const.
tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg,
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Apr 16 17:09:46 2010
@@ -409,9 +409,7 @@
// GCC does an implicit conversion to the pointer or integer ValType. This
// can fail in some cases (1i -> int**), check for this error case now.
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXMethodDecl *ConversionDecl = 0;
- if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind,
- ConversionDecl))
+ if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind))
return true;
// Okay, we have something that *can* be converted to the right type. Check
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Apr 16 17:09:46 2010
@@ -4271,113 +4271,6 @@
FinalizeVarWithDestructor(VDecl, Record);
}
-/// \brief Add the applicable constructor candidates for an initialization
-/// by constructor.
-static void AddConstructorInitializationCandidates(Sema &SemaRef,
- QualType ClassType,
- Expr **Args,
- unsigned NumArgs,
- InitializationKind Kind,
- OverloadCandidateSet &CandidateSet) {
- // C++ [dcl.init]p14:
- // If the initialization is direct-initialization, or if it is
- // copy-initialization where the cv-unqualified version of the
- // source type is the same class as, or a derived class of, the
- // class of the destination, constructors are considered. The
- // applicable constructors are enumerated (13.3.1.3), and the
- // best one is chosen through overload resolution (13.3). The
- // constructor so selected is called to initialize the object,
- // with the initializer expression(s) as its argument(s). If no
- // constructor applies, or the overload resolution is ambiguous,
- // the initialization is ill-formed.
- const RecordType *ClassRec = ClassType->getAs<RecordType>();
- assert(ClassRec && "Can only initialize a class type here");
-
- // FIXME: When we decide not to synthesize the implicitly-declared
- // constructors, we'll need to make them appear here.
-
- const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassRec->getDecl());
- DeclarationName ConstructorName
- = SemaRef.Context.DeclarationNames.getCXXConstructorName(
- SemaRef.Context.getCanonicalType(ClassType).getUnqualifiedType());
- DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName);
- Con != ConEnd; ++Con) {
- DeclAccessPair FoundDecl = DeclAccessPair::make(*Con, (*Con)->getAccess());
-
- // Find the constructor (which may be a template).
- CXXConstructorDecl *Constructor = 0;
- FunctionTemplateDecl *ConstructorTmpl= dyn_cast<FunctionTemplateDecl>(*Con);
- if (ConstructorTmpl)
- Constructor
- = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
- else
- Constructor = cast<CXXConstructorDecl>(*Con);
-
- if ((Kind.getKind() == InitializationKind::IK_Direct) ||
- (Kind.getKind() == InitializationKind::IK_Value) ||
- (Kind.getKind() == InitializationKind::IK_Copy &&
- Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) ||
- ((Kind.getKind() == InitializationKind::IK_Default) &&
- Constructor->isDefaultConstructor())) {
- if (ConstructorTmpl)
- SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
- /*ExplicitArgs*/ 0,
- Args, NumArgs, CandidateSet);
- else
- SemaRef.AddOverloadCandidate(Constructor, FoundDecl,
- Args, NumArgs, CandidateSet);
- }
- }
-}
-
-/// \brief Attempt to perform initialization by constructor
-/// (C++ [dcl.init]p14), which may occur as part of direct-initialization or
-/// copy-initialization.
-///
-/// This routine determines whether initialization by constructor is possible,
-/// but it does not emit any diagnostics in the case where the initialization
-/// is ill-formed.
-///
-/// \param ClassType the type of the object being initialized, which must have
-/// class type.
-///
-/// \param Args the arguments provided to initialize the object
-///
-/// \param NumArgs the number of arguments provided to initialize the object
-///
-/// \param Kind the type of initialization being performed
-///
-/// \returns the constructor used to initialize the object, if successful.
-/// Otherwise, emits a diagnostic and returns NULL.
-CXXConstructorDecl *
-Sema::TryInitializationByConstructor(QualType ClassType,
- Expr **Args, unsigned NumArgs,
- SourceLocation Loc,
- InitializationKind Kind) {
- // Build the overload candidate set
- OverloadCandidateSet CandidateSet(Loc);
- AddConstructorInitializationCandidates(*this, ClassType, Args, NumArgs, Kind,
- CandidateSet);
-
- // Determine whether we found a constructor we can use.
- OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, Loc, Best)) {
- case OR_Success:
- case OR_Deleted:
- // We found a constructor. Return it.
- return cast<CXXConstructorDecl>(Best->Function);
-
- case OR_No_Viable_Function:
- case OR_Ambiguous:
- // Overload resolution failed. Return nothing.
- return 0;
- }
-
- // Silence GCC warning
- return 0;
-}
-
/// \brief Given a constructor and the set of arguments provided for the
/// constructor, convert the arguments and add any required default arguments
/// to form a proper call to this constructor.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Apr 16 17:09:46 2010
@@ -3789,11 +3789,9 @@
/// CheckCastTypes - Check type constraints for casting between types.
bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
CastExpr::CastKind& Kind,
- CXXMethodDecl *& ConversionDecl,
bool FunctionalStyle) {
if (getLangOptions().CPlusPlus)
- return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, FunctionalStyle,
- ConversionDecl);
+ return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, FunctionalStyle);
DefaultFunctionArrayLvalueConversion(castExpr);
@@ -3953,25 +3951,12 @@
SourceLocation RParenLoc, ExprArg Op) {
Expr *castExpr = static_cast<Expr*>(Op.get());
- CXXMethodDecl *Method = 0;
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
- Kind, Method))
+ Kind))
return ExprError();
- if (Method) {
- // FIXME: preserve type source info here
- OwningExprResult CastArg = BuildCXXCastArgument(LParenLoc, Ty->getType(),
- Kind, Method, move(Op));
-
- if (CastArg.isInvalid())
- return ExprError();
-
- castExpr = CastArg.takeAs<Expr>();
- } else {
- Op.release();
- }
-
+ Op.release();
return Owned(new (Context) CStyleCastExpr(Ty->getType().getNonReferenceType(),
Kind, castExpr, Ty,
LParenLoc, RParenLoc));
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Apr 16 17:09:46 2010
@@ -504,21 +504,10 @@
//
if (NumExprs == 1) {
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXMethodDecl *Method = 0;
- if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, Method,
- /*FunctionalStyle=*/true))
+ if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, /*FunctionalStyle=*/true))
return ExprError();
exprs.release();
- if (Method) {
- OwningExprResult CastArg
- = BuildCXXCastArgument(TypeRange.getBegin(), Ty.getNonReferenceType(),
- Kind, Method, Owned(Exprs[0]));
- if (CastArg.isInvalid())
- return ExprError();
-
- Exprs[0] = CastArg.takeAs<Expr>();
- }
return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
TInfo, TyBeginLoc, Kind,
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Apr 16 17:09:46 2010
@@ -2036,6 +2036,10 @@
return false;
}
+bool InitializationSequence::isConstructorInitialization() const {
+ return !Steps.empty() && Steps.back().Kind == SK_ConstructorInitialization;
+}
+
void InitializationSequence::AddAddressOverloadResolutionStep(
FunctionDecl *Function,
DeclAccessPair Found) {
@@ -3510,6 +3514,7 @@
}
case SK_ConstructorInitialization: {
+ unsigned NumArgs = Args.size();
CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step->Function.Function);
@@ -3523,8 +3528,9 @@
Loc, ConstructorArgs))
return S.ExprError();
- // Build the an expression that constructs a temporary.
+ // Build the expression that constructs a temporary.
if (Entity.getKind() == InitializedEntity::EK_Temporary &&
+ NumArgs != 1 && // FIXME: Hack to work around cast weirdness
(Kind.getKind() == InitializationKind::IK_Direct ||
Kind.getKind() == InitializationKind::IK_Value)) {
// An explicitly-constructed temporary, e.g., X(1, 2).
Modified: cfe/trunk/lib/Sema/SemaInit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.h?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.h (original)
+++ cfe/trunk/lib/Sema/SemaInit.h Fri Apr 16 17:09:46 2010
@@ -606,6 +606,10 @@
/// \brief Determine whether this initialization failed due to an ambiguity.
bool isAmbiguous() const;
+ /// \brief Determine whether this initialization is direct call to a
+ /// constructor.
+ bool isConstructorInitialization() const;
+
/// \brief Add a new step in the initialization that resolves the address
/// of an overloaded function to a specific function declaration.
///
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Apr 16 17:09:46 2010
@@ -126,8 +126,12 @@
Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result";
return;
}
+ } else if (const CXXFunctionalCastExpr *FC
+ = dyn_cast<CXXFunctionalCastExpr>(E)) {
+ if (isa<CXXConstructExpr>(FC->getSubExpr()) ||
+ isa<CXXTemporaryObjectExpr>(FC->getSubExpr()))
+ return;
}
-
// Diagnose "(void*) blah" as a typo for "(void) blah".
else if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E)) {
TypeSourceInfo *TI = CE->getTypeInfoAsWritten();
Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp?rev=101549&r1=101548&r2=101549&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-2.cpp Fri Apr 16 17:09:46 2010
@@ -193,3 +193,22 @@
void f0(int **a) { C::f0(a); }
}
+
+namespace N13 {
+ class A{
+ A(const A&);
+
+ public:
+ ~A();
+ A(int);
+ template<typename T> A &operator<<(const T&);
+ };
+
+ template<typename T>
+ void f(T t) {
+ A(17) << t;
+ }
+
+ template void f(int);
+
+}
More information about the cfe-commits
mailing list