summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.h
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-02-25 01:37:24 +0000
committerJohn McCall <rjmccall@apple.com>2010-02-25 01:37:24 +0000
commit65eb879d22cc97580e9fc8f832df29c4b59499f5 (patch)
tree99db92dd66bbe3da037b7a59e523a27d16246db3 /clang/lib/Sema/SemaOverload.h
parente776fbfb82f33788ba81eb22248b8781109df337 (diff)
downloadbcm5719-llvm-65eb879d22cc97580e9fc8f832df29c4b59499f5.tar.gz
bcm5719-llvm-65eb879d22cc97580e9fc8f832df29c4b59499f5.zip
Catch more uses of uninitialized implicit conversion sequences.
When diagnosing bad conversions, skip the conversion for ignored object arguments. Fixes PR 6398. llvm-svn: 97090
Diffstat (limited to 'clang/lib/Sema/SemaOverload.h')
-rw-r--r--clang/lib/Sema/SemaOverload.h57
1 files changed, 43 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaOverload.h b/clang/lib/Sema/SemaOverload.h
index e6dfa742355..3b06e7a8dfb 100644
--- a/clang/lib/Sema/SemaOverload.h
+++ b/clang/lib/Sema/SemaOverload.h
@@ -316,14 +316,22 @@ namespace clang {
};
private:
+ enum {
+ Uninitialized = BadConversion + 1
+ };
+
/// ConversionKind - The kind of implicit conversion sequence.
- Kind ConversionKind;
+ unsigned ConversionKind;
void setKind(Kind K) {
- if (isAmbiguous()) Ambiguous.destruct();
+ destruct();
ConversionKind = K;
}
+ void destruct() {
+ if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
+ }
+
public:
union {
/// When ConversionKind == StandardConversion, provides the
@@ -343,14 +351,15 @@ namespace clang {
BadConversionSequence Bad;
};
- ImplicitConversionSequence() : ConversionKind(BadConversion) {}
+ ImplicitConversionSequence() : ConversionKind(Uninitialized) {}
~ImplicitConversionSequence() {
- if (isAmbiguous()) Ambiguous.destruct();
+ destruct();
}
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
: ConversionKind(Other.ConversionKind)
{
switch (ConversionKind) {
+ case Uninitialized: break;
case StandardConversion: Standard = Other.Standard; break;
case UserDefinedConversion: UserDefined = Other.UserDefined; break;
case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
@@ -361,26 +370,45 @@ namespace clang {
ImplicitConversionSequence &
operator=(const ImplicitConversionSequence &Other) {
- if (isAmbiguous()) Ambiguous.destruct();
+ destruct();
new (this) ImplicitConversionSequence(Other);
return *this;
}
- Kind getKind() const { return ConversionKind; }
- bool isBad() const { return ConversionKind == BadConversion; }
- bool isStandard() const { return ConversionKind == StandardConversion; }
- bool isEllipsis() const { return ConversionKind == EllipsisConversion; }
- bool isAmbiguous() const { return ConversionKind == AmbiguousConversion; }
- bool isUserDefined() const {
- return ConversionKind == UserDefinedConversion;
+ Kind getKind() const {
+ assert(isInitialized() && "querying uninitialized conversion");
+ return Kind(ConversionKind);
+ }
+ bool isBad() const { return getKind() == BadConversion; }
+ bool isStandard() const { return getKind() == StandardConversion; }
+ bool isEllipsis() const { return getKind() == EllipsisConversion; }
+ bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
+ bool isUserDefined() const { return getKind() == UserDefinedConversion; }
+
+ /// Determines whether this conversion sequence has been
+ /// initialized. Most operations should never need to query
+ /// uninitialized conversions and should assert as above.
+ bool isInitialized() const { return ConversionKind != Uninitialized; }
+
+ /// Sets this sequence as a bad conversion for an explicit argument.
+ void setBad(BadConversionSequence::FailureKind Failure,
+ Expr *FromExpr, QualType ToType) {
+ setKind(BadConversion);
+ Bad.init(Failure, FromExpr, ToType);
+ }
+
+ /// Sets this sequence as a bad conversion for an implicit argument.
+ void setBad(BadConversionSequence::FailureKind Failure,
+ QualType FromType, QualType ToType) {
+ setKind(BadConversion);
+ Bad.init(Failure, FromType, ToType);
}
- void setBad() { setKind(BadConversion); }
void setStandard() { setKind(StandardConversion); }
void setEllipsis() { setKind(EllipsisConversion); }
void setUserDefined() { setKind(UserDefinedConversion); }
void setAmbiguous() {
- if (isAmbiguous()) return;
+ if (ConversionKind == AmbiguousConversion) return;
ConversionKind = AmbiguousConversion;
Ambiguous.construct();
}
@@ -490,6 +518,7 @@ namespace clang {
bool hasAmbiguousConversion() const {
for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator
I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
+ if (!I->isInitialized()) return false;
if (I->isAmbiguous()) return true;
}
return false;
OpenPOWER on IntegriCloud