forked from OSchip/llvm-project
Enforce access control for conversion operators used in contextual
conversions (rather than just call-arguments). llvm-svn: 140244
This commit is contained in:
parent
9cb88ec8d1
commit
30909031a7
|
@ -256,7 +256,7 @@ namespace clang {
|
||||||
/// \brief The declaration that we found via name lookup, which might be
|
/// \brief The declaration that we found via name lookup, which might be
|
||||||
/// the same as \c ConversionFunction or it might be a using declaration
|
/// the same as \c ConversionFunction or it might be a using declaration
|
||||||
/// that refers to \c ConversionFunction.
|
/// that refers to \c ConversionFunction.
|
||||||
NamedDecl *FoundConversionFunction;
|
DeclAccessPair FoundConversionFunction;
|
||||||
|
|
||||||
void DebugPrint() const;
|
void DebugPrint() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1551,8 +1551,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
|
||||||
Found.getAccess() == AS_public)
|
Found.getAccess() == AS_public)
|
||||||
return AR_accessible;
|
return AR_accessible;
|
||||||
|
|
||||||
const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
|
const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
|
||||||
assert(RT && "found member operator but object expr not of record type");
|
|
||||||
CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
|
CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
|
||||||
|
|
||||||
AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
|
AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
|
||||||
|
|
|
@ -2065,7 +2065,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
|
||||||
QualType Ty,
|
QualType Ty,
|
||||||
CastKind Kind,
|
CastKind Kind,
|
||||||
CXXMethodDecl *Method,
|
CXXMethodDecl *Method,
|
||||||
NamedDecl *FoundDecl,
|
DeclAccessPair FoundDecl,
|
||||||
Expr *From) {
|
Expr *From) {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
default: assert(0 && "Unhandled cast kind!");
|
default: assert(0 && "Unhandled cast kind!");
|
||||||
|
@ -2096,6 +2096,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
|
||||||
if (Result.isInvalid())
|
if (Result.isInvalid())
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
|
S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl);
|
||||||
|
|
||||||
return S.MaybeBindToTemporary(Result.get());
|
return S.MaybeBindToTemporary(Result.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2509,7 +2509,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
||||||
User.EllipsisConversion = false;
|
User.EllipsisConversion = false;
|
||||||
}
|
}
|
||||||
User.ConversionFunction = Constructor;
|
User.ConversionFunction = Constructor;
|
||||||
User.FoundConversionFunction = Best->FoundDecl.getDecl();
|
User.FoundConversionFunction = Best->FoundDecl;
|
||||||
User.After.setAsIdentityConversion();
|
User.After.setAsIdentityConversion();
|
||||||
User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
|
User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
|
||||||
User.After.setAllToTypes(ToType);
|
User.After.setAllToTypes(ToType);
|
||||||
|
@ -2526,7 +2526,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
||||||
// implicit object parameter of the conversion function.
|
// implicit object parameter of the conversion function.
|
||||||
User.Before = Best->Conversions[0].Standard;
|
User.Before = Best->Conversions[0].Standard;
|
||||||
User.ConversionFunction = Conversion;
|
User.ConversionFunction = Conversion;
|
||||||
User.FoundConversionFunction = Best->FoundDecl.getDecl();
|
User.FoundConversionFunction = Best->FoundDecl;
|
||||||
User.EllipsisConversion = false;
|
User.EllipsisConversion = false;
|
||||||
|
|
||||||
// C++ [over.ics.user]p2:
|
// C++ [over.ics.user]p2:
|
||||||
|
@ -3367,7 +3367,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
|
||||||
ICS.UserDefined.Before = Best->Conversions[0].Standard;
|
ICS.UserDefined.Before = Best->Conversions[0].Standard;
|
||||||
ICS.UserDefined.After = Best->FinalConversion;
|
ICS.UserDefined.After = Best->FinalConversion;
|
||||||
ICS.UserDefined.ConversionFunction = Best->Function;
|
ICS.UserDefined.ConversionFunction = Best->Function;
|
||||||
ICS.UserDefined.FoundConversionFunction = Best->FoundDecl.getDecl();
|
ICS.UserDefined.FoundConversionFunction = Best->FoundDecl;
|
||||||
ICS.UserDefined.EllipsisConversion = false;
|
ICS.UserDefined.EllipsisConversion = false;
|
||||||
assert(ICS.UserDefined.After.ReferenceBinding &&
|
assert(ICS.UserDefined.After.ReferenceBinding &&
|
||||||
ICS.UserDefined.After.DirectBinding &&
|
ICS.UserDefined.After.DirectBinding &&
|
||||||
|
@ -4754,8 +4754,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
||||||
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
|
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
|
||||||
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
|
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
|
||||||
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
|
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
|
||||||
Candidate.Conversions[0].UserDefined.FoundConversionFunction
|
Candidate.Conversions[0].UserDefined.FoundConversionFunction = FoundDecl;
|
||||||
= FoundDecl.getDecl();
|
|
||||||
Candidate.Conversions[0].UserDefined.After
|
Candidate.Conversions[0].UserDefined.After
|
||||||
= Candidate.Conversions[0].UserDefined.Before;
|
= Candidate.Conversions[0].UserDefined.Before;
|
||||||
Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
|
Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
|
||||||
|
|
|
@ -168,3 +168,25 @@ namespace test7 {
|
||||||
void foo(int arg[__builtin_offsetof(B, ins)]);
|
void foo(int arg[__builtin_offsetof(B, ins)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rdar://problem/10155256
|
||||||
|
namespace test8 {
|
||||||
|
class A {
|
||||||
|
typedef void* (A::*UnspecifiedBoolType)() const;
|
||||||
|
operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test(A &a) {
|
||||||
|
if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test9 {
|
||||||
|
class A {
|
||||||
|
operator char*() const; // expected-note {{implicitly declared private here}}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test(A &a) {
|
||||||
|
delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ void t4(T *t) {
|
||||||
// PR5102
|
// PR5102
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class A {
|
class A {
|
||||||
operator T *() const;
|
public: operator T *() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void f() {
|
void f() {
|
||||||
|
|
Loading…
Reference in New Issue