From f1120de60490560d22328bcc83045b77ab46dcde Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Fri, 24 Aug 2007 22:33:52 +0000 Subject: [PATCH] This modest change insures ImplicitCastExpr's get generated for all "assignments", while includes init decls, assignment exprs, call exprs, and return statements. Here are a few examples with the correct AST's... [dylan:~/llvm/tools/clang] admin% cat impcomp.c _Complex double X; void test2(int c) { X = 5; } void foo() { int i; double d = i; double _Complex a = 5; test2(a); a = 5; d = i; } [dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang impcomp.c -parse-ast-dump Read top-level variable decl: 'X' void test2(int c) (CompoundStmt 0x2605ce0 (BinaryOperator 0x2605cc0 '_Complex double' '=' (DeclRefExpr 0x2605c70 '_Complex double' Decl='X' 0x2605af0) (ImplicitCastExpr 0x2605cb0 '_Complex double' (IntegerLiteral 0x2605c90 'int' 5)))) void foo() (CompoundStmt 0x2606030 (DeclStmt 0x2605bd0 0x2605d90 "int i") (DeclStmt 0x2605e20 0x2605de0 "double d = (ImplicitCastExpr 0x2605e10 'double' (DeclRefExpr 0x2605dc0 'int' Decl='i' 0x2605d90))") (DeclStmt 0x2605e90 0x2605e50 "_Complex double a = (ImplicitCastExpr 0x2605e80 '_Complex double' (IntegerLiteral 0x2605e30 'int' 5))") (CallExpr 0x2605f20 'void' (ImplicitCastExpr 0x2605f00 'void (*)(int)' (DeclRefExpr 0x2605ea0 'void (int)' Decl='test2' 0x2605c00)) (ImplicitCastExpr 0x2605f10 'int' (DeclRefExpr 0x2605ec0 '_Complex double' Decl='a' 0x2605e50))) (BinaryOperator 0x2605fa0 '_Complex double' '=' (DeclRefExpr 0x2605f50 '_Complex double' Decl='a' 0x2605e50) (ImplicitCastExpr 0x2605f90 '_Complex double' (IntegerLiteral 0x2605f70 'int' 5))) (BinaryOperator 0x2606010 'double' '=' (DeclRefExpr 0x2605fc0 'double' Decl='d' 0x2605de0) (ImplicitCastExpr 0x2606000 'double' (DeclRefExpr 0x2605fe0 'int' Decl='i' 0x2605d90)))) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41379 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/Sema.h | 2 +- Sema/SemaDecl.cpp | 8 ++++++-- Sema/SemaExpr.cpp | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Sema/Sema.h b/Sema/Sema.h index 7eae1822d2..e1de7d37bc 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -407,7 +407,7 @@ private: // For simple assignment, pass both expressions and a null converted type. // For compound assignment, pass both expressions and the converted type. inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] - Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType); + Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType); inline QualType CheckCommaOperands( // C99 6.5.17 Expr *&lex, Expr *&rex, SourceLocation OpLoc); inline QualType CheckConditionalOperands( // C99 6.5.15 diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 31b612cc7b..46e5a108ca 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -415,8 +415,12 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init, NewVD = MergeVarDecl(NewVD, PrevDecl); if (NewVD == 0) return 0; } - - NewVD->setInit(Init); + if (Init) { + AssignmentCheckResult result; + result = CheckSingleAssignmentConstraints(R, Init); + // FIXME: emit errors if appropriate. + NewVD->setInit(Init); + } New = NewVD; } diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index a0fa38e1d8..a86a255256 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -527,6 +527,8 @@ ParseCallExpr(ExprTy *fn, SourceLocation LParenLoc, AssignmentCheckResult result = CheckSingleAssignmentConstraints(lhsType, argExpr); + if (Args[i] != argExpr) // The expression was converted. + Args[i] = argExpr; // Make sure we store the converted expression. SourceLocation l = argExpr->getLocStart(); // decode the result (notice that AST's are still created for extensions). @@ -929,8 +931,16 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // DeclExpr's (created by ParseIdentifierExpr), it would mess up the unary // expressions that surpress this implicit conversion (&, sizeof). DefaultFunctionArrayConversion(rExpr); + + Sema::AssignmentCheckResult result; + + result = CheckAssignmentConstraints(lhsType, rExpr->getType()); - return CheckAssignmentConstraints(lhsType, rExpr->getType()); + // C99 6.5.16.1p2: The value of the right operand is converted to the + // type of the assignment expression. + if (rExpr->getType() != lhsType) + promoteExprToType(rExpr, lhsType); + return result; } Sema::AssignmentCheckResult @@ -1166,7 +1176,7 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] } inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1 - Expr *lex, Expr *rex, SourceLocation loc, QualType compoundType) + Expr *lex, Expr *&rex, SourceLocation loc, QualType compoundType) { QualType lhsType = lex->getType(); QualType rhsType = compoundType.isNull() ? rex->getType() : compoundType; -- 2.40.0