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 | ae916a14cf727b4ce3ac316f4fd780d1c83c5baf (patch) | |
tree | 58e3ef0eb588c148e9bfb24ee4a8247c75268337 /lib/Sema | |
parent | bf393be8a0b8b573ceb23ed19ac953832a2a69e4 (diff) |
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
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9339c04c51..709b944447 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/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. |