[cfe-commits] r39431 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:18 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:18 2007
New Revision: 39431
URL: http://llvm.org/viewvc/llvm-project?rev=39431&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
More refinements to UsualAssignmentConversions(). Added a call
to do the UsualUnaryConversion for arrays/functions. I believe this is
correct (but subtle). This enabled me to remove code for dealing with
arrays/functions explictly (which more closely reflects the spec).
Modified:
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39431&r1=39430&r2=39431&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:18 2007
@@ -342,6 +342,11 @@
if (const FunctionType *funcT = dyn_cast<FunctionType>(canonType)) {
resultType = funcT->getResultType();
}
+ // C99 6.5.2.2p7 - If we have a prototype, the arguments are implicitly
+ // converted, as if by assignment, to the types of the corresponding
+ // parameters, taking the type of each parameter to be the unqualified...
+ //
+ // QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs, resultType);
}
@@ -499,6 +504,13 @@
QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
Expr *rex, SourceLocation loc) {
+ // this check seems unnatural, however it necessary to insure the proper
+ // conversion of functions/arrays. If the conversion where done for all
+ // DeclExpr's (created by ParseIdentifierExpr), it would mess up the
+ // unary expressions that surpress this implicit conversion (&, sizeof).
+ if (rhsType->isFunctionType() || rhsType->isArrayType())
+ rhsType = UsualUnaryConversion(rhsType);
+
if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
return lhsType;
else if (lhsType->isPointerType()) {
@@ -507,20 +519,20 @@
const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
if (!constant || constant->getValue() != 0)
Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
- return lhsType;
+ return rhsType;
}
// FIXME: make sure the qualifier are matching
if (rhsType->isPointerType()) {
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return lhsType;
+ return rhsType;
}
} else if (rhsType->isPointerType()) {
if (lhsType->isIntegerType()) {
// 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 lhsType;
+ return rhsType;
}
// - both operands are pointers to qualified or unqualified versions of
// compatible types, and the type pointed to by the left has *all* the
@@ -528,22 +540,14 @@
if (lhsType->isPointerType()) {
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return lhsType;
+ return rhsType;
}
- } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
- /// int aryInt[3], aryInt2[3];
- /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
- if (Type::arrayTypesAreCompatible(lhsType, rhsType))
- return lhsType;
} else if (lhsType->isStructureType() && rhsType->isStructureType()) {
if (Type::structureTypesAreCompatible(lhsType, rhsType))
- return lhsType;
+ return rhsType;
} else if (lhsType->isUnionType() && rhsType->isUnionType()) {
if (Type::unionTypesAreCompatible(lhsType, rhsType))
- return lhsType;
- } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
- if (Type::functionTypesAreCompatible(lhsType, rhsType))
- return lhsType;
+ return rhsType;
}
return QualType(); // incompatible
}
@@ -676,6 +680,8 @@
QualType rhsType = rex->getType();
if ((BOP)code == BinaryOperator::Assign) { // C99 6.5.16.1
+ if (!lex->isLvalue())
+ return Diag(loc, diag::ext_typecheck_assign_non_lvalue);
if (lhsType.isConstQualified())
return Diag(loc, diag::err_typecheck_assign_const);
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39431&r1=39430&r2=39431&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:18 2007
@@ -342,6 +342,11 @@
if (const FunctionType *funcT = dyn_cast<FunctionType>(canonType)) {
resultType = funcT->getResultType();
}
+ // C99 6.5.2.2p7 - If we have a prototype, the arguments are implicitly
+ // converted, as if by assignment, to the types of the corresponding
+ // parameters, taking the type of each parameter to be the unqualified...
+ //
+ // QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs, resultType);
}
@@ -499,6 +504,13 @@
QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
Expr *rex, SourceLocation loc) {
+ // this check seems unnatural, however it necessary to insure the proper
+ // conversion of functions/arrays. If the conversion where done for all
+ // DeclExpr's (created by ParseIdentifierExpr), it would mess up the
+ // unary expressions that surpress this implicit conversion (&, sizeof).
+ if (rhsType->isFunctionType() || rhsType->isArrayType())
+ rhsType = UsualUnaryConversion(rhsType);
+
if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
return lhsType;
else if (lhsType->isPointerType()) {
@@ -507,20 +519,20 @@
const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
if (!constant || constant->getValue() != 0)
Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
- return lhsType;
+ return rhsType;
}
// FIXME: make sure the qualifier are matching
if (rhsType->isPointerType()) {
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return lhsType;
+ return rhsType;
}
} else if (rhsType->isPointerType()) {
if (lhsType->isIntegerType()) {
// 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 lhsType;
+ return rhsType;
}
// - both operands are pointers to qualified or unqualified versions of
// compatible types, and the type pointed to by the left has *all* the
@@ -528,22 +540,14 @@
if (lhsType->isPointerType()) {
if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return lhsType;
+ return rhsType;
}
- } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
- /// int aryInt[3], aryInt2[3];
- /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
- if (Type::arrayTypesAreCompatible(lhsType, rhsType))
- return lhsType;
} else if (lhsType->isStructureType() && rhsType->isStructureType()) {
if (Type::structureTypesAreCompatible(lhsType, rhsType))
- return lhsType;
+ return rhsType;
} else if (lhsType->isUnionType() && rhsType->isUnionType()) {
if (Type::unionTypesAreCompatible(lhsType, rhsType))
- return lhsType;
- } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
- if (Type::functionTypesAreCompatible(lhsType, rhsType))
- return lhsType;
+ return rhsType;
}
return QualType(); // incompatible
}
@@ -676,6 +680,8 @@
QualType rhsType = rex->getType();
if ((BOP)code == BinaryOperator::Assign) { // C99 6.5.16.1
+ if (!lex->isLvalue())
+ return Diag(loc, diag::ext_typecheck_assign_non_lvalue);
if (lhsType.isConstQualified())
return Diag(loc, diag::err_typecheck_assign_const);
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39431&r1=39430&r2=39431&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:18 2007
@@ -551,6 +551,8 @@
"assignment makes pointer from integer without a cast")
DIAG(ext_typecheck_assign_incompatible_pointer, EXTENSION,
"assignment from incompatible pointer type")
+DIAG(ext_typecheck_assign_non_lvalue, ERROR,
+ "assignment to non-lvalue")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
More information about the cfe-commits
mailing list