aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AST/Type.cpp12
-rw-r--r--Sema/SemaExpr.cpp19
-rw-r--r--Sema/SemaStmt.cpp3
-rw-r--r--clang.xcodeproj/project.pbxproj2
-rw-r--r--include/clang/AST/Type.h3
-rw-r--r--test/Parser/promote_types_in_proto.c9
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);
+}