[cfe-dev] Member expression returns type with wrong qualifiers

Steve Naroff snaroff at apple.com
Mon Feb 4 15:06:14 PST 2008


On Feb 4, 2008, at 12:15 PM, Eli Friedman wrote:

> As I mentioned before, the following:
> int a(const struct {int a;}*b) {b->a = 10;}
> is incorrectly accepted by clang.  (Relevant spec reference: C99  
> 6.5.2.3p3.)
>
> I'm not completely sure how to go about fixing this, though.  It could
> be fixed completely in the MemberExpr constructor, but that would be
> burying spec rules inside Expr.h, which seems wrong.  (Not to mention
> it would be extremely ugly.)  On the other hand, if the logic isn't in
> the constructor, serialization also needs to be able to figure out the
> type of the MemberExpr. Maybe some sort of helper would be best?
>

One solution is to extend Expr::isModifiableLvalue() and the  
MemberExpr AST to return the underlying base type.

I've enclose a quick prototype that seems to solve the problem (for  
discussion purposes...).

snaroff

[snaroff:llvm/tools/clang] snarofflocal% svn diff
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h	(revision 46647)
+++ include/clang/AST/Expr.h	(working copy)
@@ -658,6 +658,13 @@
    FieldDecl *getMemberDecl() const { return MemberDecl; }
    bool isArrow() const { return IsArrow; }

+  QualType getUnderlyingBaseType() const {
+    if (isArrow()) {
+      if (const PointerType *T = Base->getType()->getAsPointerType())
+        return T->getPointeeType();
+    }
+    return Base->getType();
+  }
    virtual SourceRange getSourceRange() const {
      return SourceRange(getBase()->getLocStart(), MemberLoc);
    }
Index: AST/Expr.cpp
===================================================================
--- AST/Expr.cpp	(revision 46647)
+++ AST/Expr.cpp	(working copy)
@@ -432,6 +432,10 @@
      if (r->hasConstFields())
        return MLV_ConstQualified;
    }
+  if (const MemberExpr *m = cast<MemberExpr>(this)) {
+    if (m->getUnderlyingBaseType().isConstQualified())
+      return MLV_ConstQualified;
+  }
    return MLV_Valid;
  }

[snaroff:llvm/tools/clang] snarofflocal% ../../Debug/bin/clang eli.c
eli.c:3:8: error: read-only variable is not assignable
   b->a = 10;
   ~~~~ ^
eli.c:5:8: error: read-only variable is not assignable
   c->b = 10;
   ~~~~ ^
2 diagnostics generated.

> -Eli
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list