[cfe-commits] r39431 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def

Steve Naroff snaroff at apple.com
Wed Jul 11 09:44:18 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:44:18 2007
New Revision: 39431

URL: http://llvm.org/viewvc/llvm-project?rev=39431&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
More refinements to UsualAssignmentConversions(). Added a call
to do the UsualUnaryConversion for arrays/functions. I believe this is
correct (but subtle). This enabled me to remove code for dealing with
arrays/functions explictly (which more closely reflects the spec).

Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39431&r1=39430&r2=39431&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:18 2007
@@ -342,6 +342,11 @@
   if (const FunctionType *funcT = dyn_cast<FunctionType>(canonType)) {
     resultType = funcT->getResultType();
   }
+  // C99 6.5.2.2p7 - If we have a prototype, the arguments are implicitly
+  // converted, as if by assignment, to the types of the corresponding
+  // parameters, taking the type of each parameter to be the unqualified...
+  //
+  // QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
   return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs, resultType);
 }
 
@@ -499,6 +504,13 @@
 
 QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
                                           Expr *rex, SourceLocation loc) {
+  // this check seems unnatural, however it necessary to insure the proper
+  // conversion of functions/arrays. If the conversion where done for all
+  // DeclExpr's (created by ParseIdentifierExpr), it would mess up the
+  // unary expressions that surpress this implicit conversion (&, sizeof).
+  if (rhsType->isFunctionType() || rhsType->isArrayType())
+    rhsType = UsualUnaryConversion(rhsType);
+    
   if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
     return lhsType;
   else if (lhsType->isPointerType()) {
@@ -507,20 +519,20 @@
       const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
       if (!constant || constant->getValue() != 0)
         Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
-      return lhsType;
+      return rhsType;
     }
     // FIXME: make sure the qualifier are matching
     if (rhsType->isPointerType()) { 
       if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
         Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-      return lhsType;
+      return 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)
         Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
-      return lhsType;
+      return rhsType;
     }
     // - both operands are pointers to qualified or unqualified versions of
     // compatible types, and the type pointed to by the left has *all* the
@@ -528,22 +540,14 @@
     if (lhsType->isPointerType()) {
       if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
         Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-      return lhsType;
+      return rhsType;
     }
-  } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
-    ///  int aryInt[3], aryInt2[3];
-    ///  aryInt = aryInt2; // gcc considers this an error (FIXME?)
-    if (Type::arrayTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
   } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
     if (Type::structureTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
+      return rhsType;
   } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
     if (Type::unionTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
-  } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
-    if (Type::functionTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
+      return rhsType;
   }
   return QualType(); // incompatible
 }
@@ -676,6 +680,8 @@
   QualType rhsType = rex->getType();
   
   if ((BOP)code == BinaryOperator::Assign) { // C99 6.5.16.1
+    if (!lex->isLvalue())
+      return Diag(loc, diag::ext_typecheck_assign_non_lvalue);
     if (lhsType.isConstQualified())
       return Diag(loc, diag::err_typecheck_assign_const);
       

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39431&r1=39430&r2=39431&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:18 2007
@@ -342,6 +342,11 @@
   if (const FunctionType *funcT = dyn_cast<FunctionType>(canonType)) {
     resultType = funcT->getResultType();
   }
+  // C99 6.5.2.2p7 - If we have a prototype, the arguments are implicitly
+  // converted, as if by assignment, to the types of the corresponding
+  // parameters, taking the type of each parameter to be the unqualified...
+  //
+  // QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
   return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs, resultType);
 }
 
@@ -499,6 +504,13 @@
 
 QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
                                           Expr *rex, SourceLocation loc) {
+  // this check seems unnatural, however it necessary to insure the proper
+  // conversion of functions/arrays. If the conversion where done for all
+  // DeclExpr's (created by ParseIdentifierExpr), it would mess up the
+  // unary expressions that surpress this implicit conversion (&, sizeof).
+  if (rhsType->isFunctionType() || rhsType->isArrayType())
+    rhsType = UsualUnaryConversion(rhsType);
+    
   if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
     return lhsType;
   else if (lhsType->isPointerType()) {
@@ -507,20 +519,20 @@
       const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
       if (!constant || constant->getValue() != 0)
         Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
-      return lhsType;
+      return rhsType;
     }
     // FIXME: make sure the qualifier are matching
     if (rhsType->isPointerType()) { 
       if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
         Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-      return lhsType;
+      return 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)
         Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
-      return lhsType;
+      return rhsType;
     }
     // - both operands are pointers to qualified or unqualified versions of
     // compatible types, and the type pointed to by the left has *all* the
@@ -528,22 +540,14 @@
     if (lhsType->isPointerType()) {
       if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
         Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-      return lhsType;
+      return rhsType;
     }
-  } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
-    ///  int aryInt[3], aryInt2[3];
-    ///  aryInt = aryInt2; // gcc considers this an error (FIXME?)
-    if (Type::arrayTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
   } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
     if (Type::structureTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
+      return rhsType;
   } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
     if (Type::unionTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
-  } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
-    if (Type::functionTypesAreCompatible(lhsType, rhsType))
-      return lhsType;
+      return rhsType;
   }
   return QualType(); // incompatible
 }
@@ -676,6 +680,8 @@
   QualType rhsType = rex->getType();
   
   if ((BOP)code == BinaryOperator::Assign) { // C99 6.5.16.1
+    if (!lex->isLvalue())
+      return Diag(loc, diag::ext_typecheck_assign_non_lvalue);
     if (lhsType.isConstQualified())
       return Diag(loc, diag::err_typecheck_assign_const);
       

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39431&r1=39430&r2=39431&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:18 2007
@@ -551,6 +551,8 @@
      "assignment makes pointer from integer without a cast")
 DIAG(ext_typecheck_assign_incompatible_pointer, EXTENSION,
      "assignment from incompatible pointer type")
+DIAG(ext_typecheck_assign_non_lvalue, ERROR,
+     "assignment to non-lvalue")
 
 // Statements.
 DIAG(err_continue_not_in_loop, ERROR,





More information about the cfe-commits mailing list