[cfe-commits] r39601 - in /cfe/cfe/trunk: Sema/Sema.h Sema/SemaExpr.cpp Sema/SemaStmt.cpp clang.xcodeproj/project.pbxproj
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:46:07 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:46:07 2007
New Revision: 39601
URL: http://llvm.org/viewvc/llvm-project?rev=39601&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
The following code illustrates a bug in the semantic analysis for assignments:
int func() {
int *P;
char *x;
P = x; // type of this assignment expression should be "int *", NOT "char *".
}
While the type checking/diagnostics are correct, the type of the assignment
expression is incorrect (which shows up during code gen). With the fix,
the llvm code looks correct...
[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang cast.c -emit-llvm
cast.c:4:5: warning: incompatible pointer types assigning 'char *' to 'int *'
P = x; // type of assignment expression is "int *", NOT "char *".
~ ^ ~
; ModuleID = 'foo'
define i32 @func() {
entry:
%P = alloca i32* ; <i32**> [#uses=1]
%x = alloca i8* ; <i8**> [#uses=1]
%allocapt = bitcast i32 undef to i32 ; <i32> [#uses=0]
%tmp = load i8** %x ; <i8*> [#uses=1]
%conv = bitcast i8* %tmp to i32* ; <i32*> [#uses=1]
store i32* %conv, i32** %P
ret i32 undef
}
Even though the fix was simple, I decided to rename/refactor the surrounding code
to make a clearer distinction between constraint checking and conversion.
- Renamed AssignmentConversionResult -> AssignmentCheckResult.
- Renamed UsualAssignmentConversions -> CheckAssignmentConstraints.
- Changed the return type of CheckAssignmentConstraints and CheckPointerTypesForAssignment
from QualType -> AssignmentCheckResult. These routines no longer take a reference to the result (obviously).
- Changed CheckAssignmentOperands to return the correct type (with spec annotations).
Modified:
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/Sema/SemaStmt.cpp
cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39601&r1=39600&r2=39601&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:07 2007
@@ -273,7 +273,7 @@
// or array, this routine simply returns the input type (unmodified).
QualType DefaultFunctionArrayConversion(QualType t);
- enum AssignmentConversionResult {
+ enum AssignmentCheckResult {
Compatible,
Incompatible,
PointerFromInt,
@@ -281,14 +281,13 @@
IncompatiblePointer,
CompatiblePointerDiscardsQualifiers
};
- // UsualAssignmentConversions - conversions for assignment, argument passing,
+ // CheckAssignmentConstraints - conversions for assignment, argument passing,
// variable initialization, and function return values. Currently used by
- // CheckAssignmentOperands, ParseCallExpr, and ParseReturnStmt.
- QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
- AssignmentConversionResult &r);
- // Helper function for UsualAssignmentConversions (C99 6.5.16.1p1)
- QualType CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType,
- AssignmentConversionResult &r);
+ // CheckAssignmentOperands, ParseCallExpr, and ParseReturnStmt. C99 6.5.16.
+ AssignmentCheckResult CheckAssignmentConstraints(QualType lhs, QualType rhs);
+ // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
+ AssignmentCheckResult CheckPointerTypesForAssignment(QualType lhsType,
+ QualType rhsType);
/// the following "Check" methods will return a valid/converted QualType
/// or a null QualType (indicating an error diagnostic was issued).
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39601&r1=39600&r2=39601&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:46:07 2007
@@ -415,9 +415,9 @@
if (lhsType == rhsType) // common case, fast path...
continue;
- AssignmentConversionResult result;
- UsualAssignmentConversions(lhsType, rhsType, result);
-
+
+ AssignmentCheckResult result = CheckAssignmentConstraints(lhsType,
+ rhsType);
SourceLocation l = argExpr->getLocStart();
// decode the result (notice that AST's are still created for extensions).
@@ -634,9 +634,8 @@
// routine is it effectively iqnores the qualifiers on the top level pointee.
// This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3].
// FIXME: add a couple examples in this comment.
-QualType Sema::CheckPointerTypesForAssignment(QualType lhsType,
- QualType rhsType,
- AssignmentConversionResult &r) {
+Sema::AssignmentCheckResult
+Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
QualType lhptee, rhptee;
// get the "pointed to" type (ignoring qualifiers at the top level)
@@ -647,6 +646,8 @@
lhptee = lhptee.getCanonicalType();
rhptee = rhptee.getCanonicalType();
+ AssignmentCheckResult r = Compatible;
+
// C99 6.5.16.1p1: This following citation is common to constraints
// 3 & 4 (below). ...and the type *pointed to* by the left has all the
// qualifiers of the type *pointed to* by the right;
@@ -668,10 +669,10 @@
else if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(),
rhptee.getUnqualifiedType()))
r = IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
- return rhsType;
+ return r;
}
-/// UsualAssignmentConversions (C99 6.5.16) - This routine currently
+/// CheckAssignmentConstraints (C99 6.5.16) - This routine currently
/// has code to accommodate several GCC extensions when type checking
/// pointers. Here are some objectionable examples that GCC considers warnings:
///
@@ -688,44 +689,37 @@
/// C99 spec dictates.
/// Note: the warning above turn into errors when -pedantic-errors is enabled.
///
-QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
- AssignmentConversionResult &r) {
+Sema::AssignmentCheckResult
+Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
// This check seems unnatural, however it is necessary to insure the proper
// conversion of functions/arrays. If the conversion were done for all
// DeclExpr's (created by ParseIdentifierExpr), it would mess up the unary
// expressions that surpress this implicit conversion (&, sizeof).
rhsType = DefaultFunctionArrayConversion(rhsType);
- r = Compatible;
if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
- return lhsType;
+ return Compatible;
else if (lhsType->isPointerType()) {
- if (rhsType->isIntegerType()) {
- r = PointerFromInt;
- return rhsType;
- }
+ if (rhsType->isIntegerType())
+ return PointerFromInt;
+
if (rhsType->isPointerType())
- return CheckPointerTypesForAssignment(lhsType, rhsType, r);
+ return CheckPointerTypesForAssignment(lhsType, 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)
- r = IntFromPointer;
- return rhsType;
- }
+ // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+ if ((lhsType->isIntegerType()) && (lhsType != Context.BoolTy))
+ return IntFromPointer;
+
if (lhsType->isPointerType())
- return CheckPointerTypesForAssignment(lhsType, rhsType, r);
+ return CheckPointerTypesForAssignment(lhsType, rhsType);
} else if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
if (Type::tagTypesAreCompatible(lhsType, rhsType))
- return rhsType;
+ return Compatible;
} else if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
if (Type::referenceTypesAreCompatible(lhsType, rhsType))
- // C++ 5.17p1: ...the type of the assignment exression is that of its left
- // operand.
- return lhsType;
+ return Compatible;
}
- r = Incompatible;
- return QualType();
+ return Incompatible;
}
inline void Sema::InvalidOperands(SourceLocation loc, Expr *lex, Expr *rex) {
@@ -898,8 +892,7 @@
if (lhsType == rhsType) // common case, fast path...
return lhsType;
- AssignmentConversionResult result;
- QualType resType = UsualAssignmentConversions(lhsType, rhsType, result);
+ AssignmentCheckResult result = CheckAssignmentConstraints(lhsType, rhsType);
// decode the result (notice that extensions still return a type).
switch (result) {
@@ -935,7 +928,13 @@
lex->getSourceRange(), rex->getSourceRange());
break;
}
- return hadError ? QualType() : resType;
+ // C99 6.5.16p3: The type of an assignment expression is the type of the
+ // left operand unless the left operand has qualified type, in which case
+ // it is the unqualified version of the type of the left operand.
+ // C99 6.5.16.1p2: In simple assignment, the value of the right operand
+ // is converted to the type of the assignment expression (above).
+ // C++ 5.17p1: the type of the assignment expression is that of its left oprdu.
+ return hadError ? QualType() : lhsType.getUnqualifiedType();
}
inline QualType Sema::CheckCommaOperands( // C99 6.5.17
Modified: cfe/cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaStmt.cpp?rev=39601&r1=39600&r2=39601&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaStmt.cpp Wed Jul 11 11:46:07 2007
@@ -241,8 +241,7 @@
// C99 6.8.6.4p3(136): The return statement is not an assignment. The
// overlap restriction of subclause 6.5.16.1 does not apply to the case of
// function return.
- AssignmentConversionResult result;
- QualType resType = UsualAssignmentConversions(lhsType, rhsType, result);
+ AssignmentCheckResult result = CheckAssignmentConstraints(lhsType, rhsType);
bool hadError = false;
// decode the result (notice that extensions still return a type).
Modified: cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=39601&r1=39600&r2=39601&view=diff
==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:46:07 2007
@@ -10,6 +10,8 @@
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
+ 84916BE50C161E580080778F /* Attr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84916BE40C161E580080778F /* Attr.cpp */; };
+ 84916BE70C161E800080778F /* Attr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84916BE60C161E800080778F /* Attr.h */; };
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */; };
DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
@@ -106,6 +108,23 @@
DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
/* End PBXBuildFile section */
+/* Begin PBXBuildStyle section */
+ 84916C3B0C1736920080778F /* Development */ = {
+ isa = PBXBuildStyle;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ };
+ name = Development;
+ };
+ 84916C3C0C1736920080778F /* Deployment */ = {
+ isa = PBXBuildStyle;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ };
+ name = Deployment;
+ };
+/* End PBXBuildStyle section */
+
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@@ -160,6 +179,7 @@
DE928B200C0565B000231DA4 /* ModuleBuilder.h in CopyFiles */,
DE928B7D0C0A615100231DA4 /* CodeGenModule.h in CopyFiles */,
DE928B810C0A615B00231DA4 /* CodeGenFunction.h in CopyFiles */,
+ 84916BE70C161E800080778F /* Attr.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
@@ -169,6 +189,8 @@
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
+ 84916BE40C161E580080778F /* Attr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Attr.cpp; path = AST/Attr.cpp; sourceTree = "<group>"; };
+ 84916BE60C161E800080778F /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Attr.h; path = include/clang/AST/Attr.h; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
@@ -432,6 +454,8 @@
DED677C80B6C854100AAD4A3 /* Builtins.cpp */,
DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */,
DE0FCB330A9C21F100248FD5 /* Expr.cpp */,
+ 84916BE60C161E800080778F /* Attr.h */,
+ 84916BE40C161E580080778F /* Attr.cpp */,
DE3452400AEF1A2D00DBC861 /* Stmt.cpp */,
DE75EDF00B06880E0020CF81 /* Type.cpp */,
DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
@@ -547,6 +571,12 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ buildSettings = {
+ };
+ buildStyles = (
+ 84916C3B0C1736920080778F /* Development */,
+ 84916C3C0C1736920080778F /* Deployment */,
+ );
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
@@ -611,6 +641,7 @@
DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */,
DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */,
DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */,
+ 84916BE50C161E580080778F /* Attr.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
More information about the cfe-commits
mailing list