diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 72 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 8 |
2 files changed, 64 insertions, 16 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c63d973425..4fd8f66108 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4539,11 +4539,12 @@ bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { /// both shall have the identically qualified version of a compatible type. /// C99 6.2.7p1: Two types have compatible types if their types are the /// same. See 6.7.[2,3,5] for additional rules. -bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) { +bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS, + bool CompareUnqualified) { if (getLangOptions().CPlusPlus) return hasSameType(LHS, RHS); - return !mergeTypes(LHS, RHS).isNull(); + return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull(); } bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) { @@ -4551,7 +4552,8 @@ bool ASTContext::typesAreBlockPointerCompatible(QualType LHS, QualType RHS) { } QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, - bool OfBlockPointer) { + bool OfBlockPointer, + bool Unqualified) { const FunctionType *lbase = lhs->getAs<FunctionType>(); const FunctionType *rbase = rhs->getAs<FunctionType>(); const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase); @@ -4562,13 +4564,26 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, // Check return type QualType retType; if (OfBlockPointer) - retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true); + retType = mergeTypes(rbase->getResultType(), lbase->getResultType(), true, + Unqualified); else - retType = mergeTypes(lbase->getResultType(), rbase->getResultType()); + retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), + false, Unqualified); if (retType.isNull()) return QualType(); - if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType())) + + if (Unqualified) + retType = retType.getUnqualifiedType(); + + CanQualType LRetType = getCanonicalType(lbase->getResultType()); + CanQualType RRetType = getCanonicalType(rbase->getResultType()); + if (Unqualified) { + LRetType = LRetType.getUnqualifiedType(); + RRetType = RRetType.getUnqualifiedType(); + } + + if (getCanonicalType(retType) != LRetType) allLTypes = false; - if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType())) + if (getCanonicalType(retType) != RRetType) allRTypes = false; // FIXME: double check this // FIXME: should we error if lbase->getRegParmAttr() != 0 && @@ -4613,9 +4628,19 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, for (unsigned i = 0; i < lproto_nargs; i++) { QualType largtype = lproto->getArgType(i).getUnqualifiedType(); QualType rargtype = rproto->getArgType(i).getUnqualifiedType(); - QualType argtype = mergeTypes(largtype, rargtype, OfBlockPointer); + QualType argtype = mergeTypes(largtype, rargtype, OfBlockPointer, + Unqualified); if (argtype.isNull()) return QualType(); + + if (Unqualified) + argtype = argtype.getUnqualifiedType(); + types.push_back(argtype); + if (Unqualified) { + largtype = largtype.getUnqualifiedType(); + rargtype = rargtype.getUnqualifiedType(); + } + if (getCanonicalType(argtype) != getCanonicalType(largtype)) allLTypes = false; if (getCanonicalType(argtype) != getCanonicalType(rargtype)) @@ -4671,7 +4696,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, } QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, - bool OfBlockPointer) { + bool OfBlockPointer, + bool Unqualified) { // C++ [expr]: If an expression initially has the type "reference to T", the // type is adjusted to "T" prior to any further analysis, the expression // designates the object or function denoted by the reference, and the @@ -4679,6 +4705,11 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, // the expression is a function call (possibly inside parentheses). assert(!LHS->getAs<ReferenceType>() && "LHS is a reference type?"); assert(!RHS->getAs<ReferenceType>() && "RHS is a reference type?"); + + if (Unqualified) { + LHS = LHS.getUnqualifiedType(); + RHS = RHS.getUnqualifiedType(); + } QualType LHSCan = getCanonicalType(LHS), RHSCan = getCanonicalType(RHS); @@ -4790,7 +4821,12 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, // Merge two pointer types, while trying to preserve typedef info QualType LHSPointee = LHS->getAs<PointerType>()->getPointeeType(); QualType RHSPointee = RHS->getAs<PointerType>()->getPointeeType(); - QualType ResultType = mergeTypes(LHSPointee, RHSPointee); + if (Unqualified) { + LHSPointee = LHSPointee.getUnqualifiedType(); + RHSPointee = RHSPointee.getUnqualifiedType(); + } + QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false, + Unqualified); if (ResultType.isNull()) return QualType(); if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) return LHS; @@ -4803,7 +4839,12 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, // Merge two block pointer types, while trying to preserve typedef info QualType LHSPointee = LHS->getAs<BlockPointerType>()->getPointeeType(); QualType RHSPointee = RHS->getAs<BlockPointerType>()->getPointeeType(); - QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer); + if (Unqualified) { + LHSPointee = LHSPointee.getUnqualifiedType(); + RHSPointee = RHSPointee.getUnqualifiedType(); + } + QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer, + Unqualified); if (ResultType.isNull()) return QualType(); if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) return LHS; @@ -4820,7 +4861,12 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, QualType LHSElem = getAsArrayType(LHS)->getElementType(); QualType RHSElem = getAsArrayType(RHS)->getElementType(); - QualType ResultType = mergeTypes(LHSElem, RHSElem); + if (Unqualified) { + LHSElem = LHSElem.getUnqualifiedType(); + RHSElem = RHSElem.getUnqualifiedType(); + } + + QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified); if (ResultType.isNull()) return QualType(); if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS; @@ -4854,7 +4900,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, ArrayType::ArraySizeModifier(), 0); } case Type::FunctionNoProto: - return mergeFunctionTypes(LHS, RHS, OfBlockPointer); + return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified); case Type::Record: case Type::Enum: return QualType(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1836c47fdc..9657b8deb9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1246,7 +1246,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { NewProto->getArgType(Idx))) { ArgTypes.push_back(NewParm->getType()); } else if (Context.typesAreCompatible(OldParm->getType(), - NewParm->getType())) { + NewParm->getType(), + /*CompareUnqualified=*/true)) { GNUCompatibleParamWarning Warn = { OldParm, NewParm, NewProto->getArgType(Idx) }; Warnings.push_back(Warn); @@ -1261,8 +1262,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { diag::ext_param_promoted_not_compatible_with_prototype) << Warnings[Warn].PromotedType << Warnings[Warn].OldParm->getType(); - Diag(Warnings[Warn].OldParm->getLocation(), - diag::note_previous_declaration); + if (Warnings[Warn].OldParm->getLocation().isValid()) + Diag(Warnings[Warn].OldParm->getLocation(), + diag::note_previous_declaration); } New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0], |