diff options
-rw-r--r-- | AST/Type.cpp | 12 | ||||
-rw-r--r-- | Sema/SemaExpr.cpp | 19 | ||||
-rw-r--r-- | Sema/SemaStmt.cpp | 3 | ||||
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 3 | ||||
-rw-r--r-- | test/Parser/promote_types_in_proto.c | 9 |
6 files changed, 34 insertions, 14 deletions
diff --git a/AST/Type.cpp b/AST/Type.cpp index 4e415e4ab6..b09d3afa63 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -84,8 +84,16 @@ const ReferenceType *Type::isReferenceType() const { return 0; } -bool Type::isArrayType() const { - return isa<ArrayType>(CanonicalType); +const ArrayType *Type::isArrayType() const { + // If this is directly a reference type, return it. + if (const ArrayType *ATy = dyn_cast<ArrayType>(this)) + return ATy; + + // If this is a typedef for an array type, strip the typedef off without + // losing all typedef information. + if (isa<ArrayType>(CanonicalType)) + return cast<ArrayType>(cast<TypedefType>(this)->LookThroughTypedefs()); + return 0; } bool Type::isStructureType() const { diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 7e0b641276..abc3ce3f7a 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -433,10 +433,15 @@ ParseCallExpr(ExprTy *fn, SourceLocation LParenLoc, QualType lhsType = proto->getArgType(i); QualType rhsType = argExpr->getType(); - - if (lhsType == rhsType) // common case, fast path... - continue; + + // C99 6.7.5.3p7 + if (const ArrayType *ary = lhsType->isArrayType()) + lhsType = Context.getPointerType(ary->getElementType()); + // C99 6.7.5.3p8 + if (lhsType->isFunctionType()) + lhsType = Context.getPointerType(lhsType); + AssignmentCheckResult result = CheckSingleAssignmentConstraints(lhsType, argExpr); SourceLocation l = argExpr->getLocStart(); @@ -638,7 +643,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&e) { } if (t->isFunctionType()) promoteExprToType(e, Context.getPointerType(t)); - else if (const ArrayType *ary = dyn_cast<ArrayType>(t.getCanonicalType())) + else if (const ArrayType *ary = t->isArrayType()) promoteExprToType(e, Context.getPointerType(ary->getElementType())); } @@ -793,6 +798,9 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { /// Sema::AssignmentCheckResult Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { + if (lhsType == rhsType) // common case, fast path... + return Compatible; + if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) { if (lhsType->isVectorType() || rhsType->isVectorType()) { if (lhsType.getCanonicalType() != rhsType.getCanonicalType()) @@ -1066,9 +1074,6 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1 lhsType.getAsString(), lex->getSourceRange()); return QualType(); } - if (lhsType == rhsType) // common case, fast path... - return lhsType; - AssignmentCheckResult result; if (compoundType.isNull()) diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp index f19737e30a..f9e2c0a21a 100644 --- a/Sema/SemaStmt.cpp +++ b/Sema/SemaStmt.cpp @@ -318,9 +318,6 @@ Sema::ParseReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { // we have a non-void function with an expression, continue checking QualType rhsType = RetValExp->getType(); - if (lhsType == rhsType) // common case, fast path... - return new ReturnStmt(RetValExp); - // 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. diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index ff84ac7c23..bb772fa182 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -191,7 +191,7 @@ 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 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>"; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; }; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 29472b4fe8..0f4770860c 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -35,6 +35,7 @@ namespace clang { class PointerType; class ReferenceType; class VectorType; + class ArrayType; /// QualType - For efficiency, we don't store CVR-qualified types as nodes on /// their own: instead each reference to a type stores the qualifiers. This @@ -237,7 +238,7 @@ public: bool isDerivedType() const; const PointerType *isPointerType() const; const ReferenceType *isReferenceType() const; - bool isArrayType() const; + const ArrayType *isArrayType() const; bool isStructureType() const; bool isUnionType() const; diff --git a/test/Parser/promote_types_in_proto.c b/test/Parser/promote_types_in_proto.c new file mode 100644 index 0000000000..40617a2a7d --- /dev/null +++ b/test/Parser/promote_types_in_proto.c @@ -0,0 +1,9 @@ +// RUN: clang %s +void functionPromotion(void f(char *const [])); +void arrayPromotion(char * const argv[]); + +int whatever(int argc, char *argv[]) +{ + arrayPromotion(argv); + functionPromotion(arrayPromotion); +} |