Bug #:
Submitted by: Reviewed by: - implement Type::functionTypesAreCompatible(). - fix bug in Sema::CheckAssignmentOperands(). Spec allows any pointer type to be assigned to _Bool. llvm-svn: 39428
This commit is contained in:
parent
dd92b932e0
commit
38a9dae33f
|
@ -646,10 +646,14 @@ Action::ExprResult Sema::CheckAssignmentOperands(
|
|||
}
|
||||
} else if (rhsType->isPointerType()) {
|
||||
if (lhsType->isIntegerType()) {
|
||||
Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
|
||||
// C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
|
||||
if (lhsType != Context.BoolTy)
|
||||
Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
|
||||
return new BinaryOperator(lex, rex, (BOP)code, lhsType);
|
||||
}
|
||||
// FIXME: make sure the qualifier are matching
|
||||
// - both operands are pointers to qualified or unqualified versions of
|
||||
// compatible types, and the type pointed to by the left has *all* the
|
||||
// qualifiers of the type pointed to by the right;
|
||||
if (lhsType->isPointerType()) {
|
||||
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
|
||||
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
|
||||
|
|
|
@ -106,7 +106,45 @@ bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
|
|||
}
|
||||
|
||||
bool Type::functionTypesAreCompatible(QualType lhs, QualType rhs) {
|
||||
return true; // FIXME: add more checking
|
||||
const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
|
||||
const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
|
||||
const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
|
||||
const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
|
||||
|
||||
// first check the return types (common between C99 and K&R).
|
||||
if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
|
||||
return false;
|
||||
|
||||
if (lproto && rproto) { // two C99 style function prototypes
|
||||
unsigned lproto_nargs = lproto->getNumArgs();
|
||||
unsigned rproto_nargs = rproto->getNumArgs();
|
||||
|
||||
if (lproto_nargs != rproto_nargs)
|
||||
return false;
|
||||
|
||||
// both prototypes have the same number of arguments.
|
||||
if ((lproto->isVariadic() && !rproto->isVariadic()) ||
|
||||
(rproto->isVariadic() && !lproto->isVariadic()))
|
||||
return false;
|
||||
|
||||
// The use of ellipsis agree...now check the argument types.
|
||||
for (unsigned i = 0; i < lproto_nargs; i++)
|
||||
if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (!lproto && !rproto) // two K&R style function decls, nothing to do.
|
||||
return true;
|
||||
|
||||
// we have a mixture of K&R style with C99 prototypes
|
||||
const FunctionTypeProto *proto = lproto ? lproto : rproto;
|
||||
|
||||
if (proto->isVariadic())
|
||||
return false;
|
||||
|
||||
// FIXME: Each parameter type T in the prototype must be compatible with the
|
||||
// type resulting from applying the usual argument conversions to T.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
|
||||
|
@ -123,6 +161,8 @@ bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
|
|||
|
||||
bool Type::typesAreCompatible(QualType lcanon, QualType rcanon) {
|
||||
// If two types are identical, they are are compatible
|
||||
// C99 6.7.3p9: For two qualified types to be compatible, both shall have
|
||||
// the identically qualified version of a compatible type.
|
||||
if (lcanon == rcanon)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -646,10 +646,14 @@ Action::ExprResult Sema::CheckAssignmentOperands(
|
|||
}
|
||||
} else if (rhsType->isPointerType()) {
|
||||
if (lhsType->isIntegerType()) {
|
||||
Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
|
||||
// C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
|
||||
if (lhsType != Context.BoolTy)
|
||||
Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
|
||||
return new BinaryOperator(lex, rex, (BOP)code, lhsType);
|
||||
}
|
||||
// FIXME: make sure the qualifier are matching
|
||||
// - both operands are pointers to qualified or unqualified versions of
|
||||
// compatible types, and the type pointed to by the left has *all* the
|
||||
// qualifiers of the type pointed to by the right;
|
||||
if (lhsType->isPointerType()) {
|
||||
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
|
||||
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
|
||||
|
|
|
@ -94,6 +94,23 @@
|
|||
DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXBuildStyle section */
|
||||
847E78660BE8363100F1DB4C /* Development */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
847E78670BE8363100F1DB4C /* Deployment */ = {
|
||||
isa = PBXBuildStyle;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
};
|
||||
name = Deployment;
|
||||
};
|
||||
/* End PBXBuildStyle section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8DD76F690486A84900D96B5E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
|
@ -476,10 +493,15 @@
|
|||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
||||
buildSettings = {
|
||||
};
|
||||
buildStyles = (
|
||||
847E78660BE8363100F1DB4C /* Development */,
|
||||
847E78670BE8363100F1DB4C /* Deployment */,
|
||||
);
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8DD76F620486A84900D96B5E /* clang */,
|
||||
);
|
||||
|
|
|
@ -215,8 +215,7 @@ public:
|
|||
bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
|
||||
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
|
||||
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
|
||||
bool isVoidType() const; // C99 6.2.5p19
|
||||
|
||||
|
||||
/// Derived types (C99 6.2.5p20). isFunctionType() is also a derived type.
|
||||
bool isDerivedType() const;
|
||||
bool isPointerType() const;
|
||||
|
@ -224,8 +223,9 @@ public:
|
|||
bool isStructureType() const;
|
||||
bool isUnionType() const;
|
||||
|
||||
bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
|
||||
bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
|
||||
bool isVoidType() const; // C99 6.2.5p19
|
||||
bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
|
||||
bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
|
||||
|
||||
bool isLvalue() const; // C99 6.3.2.1
|
||||
|
||||
|
|
Loading…
Reference in New Issue