]> granicus.if.org Git - clang/commitdiff
This modest change insures ImplicitCastExpr's get generated for all "assignments",
authorSteve Naroff <snaroff@apple.com>
Fri, 24 Aug 2007 22:33:52 +0000 (22:33 +0000)
committerSteve Naroff <snaroff@apple.com>
Fri, 24 Aug 2007 22:33:52 +0000 (22:33 +0000)
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
Sema/SemaDecl.cpp
Sema/SemaExpr.cpp

index 7eae1822d2eaf0764ce59be4720017e461233148..e1de7d37bcee524884dc029095b00438e179ba2a 100644 (file)
@@ -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
index 31b612cc7b64c9b4761776f3c53b719bf4a153c1..46e5a108ca5df26b3a321c6837eaddab77680a38 100644 (file)
@@ -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;
   }
   
index a0fa38e1d86295af4a888638fba19efb4c70d717..a86a255256461d563bf56882c608a5f6f53b309f 100644 (file)
@@ -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;