diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-04-05 22:30:04 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-04-05 22:30:04 +0000 |
commit | 57a75390fcfc4fc7e019817aa4a0b3dc3675827e (patch) | |
tree | d44b8f8530fd7e471e94e77c04169c2b6b2a7fd7 /clang/lib/Sema | |
parent | c806b90717566229ffbaa032a05bf3aded8822a7 (diff) | |
download | bcm5719-llvm-57a75390fcfc4fc7e019817aa4a0b3dc3675827e.tar.gz bcm5719-llvm-57a75390fcfc4fc7e019817aa4a0b3dc3675827e.zip |
Properly implement the C rules for composite types for qualified pointers in conditionals. Patch by Tim Northover.
llvm-svn: 154134
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9339c04c513..709b944447e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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. |