зеркало из https://github.com/microsoft/clang-1.git
Properly implement the C rules for composite types for qualified pointers in conditionals. Patch by Tim Northover.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154134 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bf393be8a0
Коммит
ae916a14cf
|
@ -4568,8 +4568,28 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
rhptee = RHSTy->castAs<PointerType>()->getPointeeType();
|
||||
}
|
||||
|
||||
if (!S.Context.typesAreCompatible(lhptee.getUnqualifiedType(),
|
||||
rhptee.getUnqualifiedType())) {
|
||||
// C99 6.5.15p6: If both operands are pointers to compatible types or to
|
||||
// differently qualified versions of compatible types, the result type is
|
||||
// a pointer to an appropriately qualified version of the composite
|
||||
// type.
|
||||
|
||||
// Only CVR-qualifiers exist in the standard, and the differently-qualified
|
||||
// clause doesn't make sense for our extensions. E.g. address space 2 should
|
||||
// be incompatible with address space 3: they may live on different devices or
|
||||
// anything.
|
||||
Qualifiers lhQual = lhptee.getQualifiers();
|
||||
Qualifiers rhQual = rhptee.getQualifiers();
|
||||
|
||||
unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
|
||||
lhQual.removeCVRQualifiers();
|
||||
rhQual.removeCVRQualifiers();
|
||||
|
||||
lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);
|
||||
rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);
|
||||
|
||||
QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee);
|
||||
|
||||
if (CompositeTy.isNull()) {
|
||||
S.Diag(Loc, diag::warn_typecheck_cond_incompatible_pointers)
|
||||
<< LHSTy << RHSTy << LHS.get()->getSourceRange()
|
||||
<< RHS.get()->getSourceRange();
|
||||
|
@ -4583,16 +4603,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
}
|
||||
|
||||
// The pointer types are compatible.
|
||||
// C99 6.5.15p6: If both operands are pointers to compatible types *or* to
|
||||
// differently qualified versions of compatible types, the result type is
|
||||
// a pointer to an appropriately qualified version of the *composite*
|
||||
// type.
|
||||
// FIXME: Need to calculate the composite type.
|
||||
// FIXME: Need to add qualifiers
|
||||
QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual);
|
||||
ResultTy = S.Context.getPointerType(ResultTy);
|
||||
|
||||
LHS = S.ImpCastExprToType(LHS.take(), LHSTy, CK_BitCast);
|
||||
RHS = S.ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
|
||||
return LHSTy;
|
||||
LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
|
||||
RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
|
||||
return ResultTy;
|
||||
}
|
||||
|
||||
/// \brief Return the resulting type when the operands are both block pointers.
|
||||
|
|
|
@ -60,6 +60,23 @@ void foo() {
|
|||
test0 = test0 ? EVal : test1; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
|
||||
test0 = test0 ? test1 : EVal; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
|
||||
|
||||
const int *const_int;
|
||||
int *nonconst_int;
|
||||
*(test0 ? const_int : nonconst_int) = 42; // expected-error {{read-only variable is not assignable}}
|
||||
*(test0 ? nonconst_int : const_int) = 42; // expected-error {{read-only variable is not assignable}}
|
||||
|
||||
// The composite type here should be "int (*)[12]", fine for the sizeof
|
||||
int (*incomplete)[];
|
||||
int (*complete)[12];
|
||||
sizeof(*(test0 ? incomplete : complete)); // expected-warning {{expression result unused}}
|
||||
sizeof(*(test0 ? complete : incomplete)); // expected-warning {{expression result unused}}
|
||||
|
||||
int __attribute__((address_space(2))) *adr2;
|
||||
int __attribute__((address_space(3))) *adr3;
|
||||
test0 ? adr2 : adr3; // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
|
||||
|
||||
// Make sure address-space mask ends up in the result type
|
||||
(test0 ? (test0 ? adr2 : adr2) : nonconst_int); // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
int Postgresql() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче