[cfe-commits] r40831 - in /cfe/trunk: Sema/SemaExpr.cpp include/clang/AST/Decl.h test/Parser/parmvardecl_conversion.c
Steve Naroff
snaroff at apple.com
Sat Aug 4 19:16:32 PDT 2007
Author: snaroff
Date: Sat Aug 4 21:16:31 2007
New Revision: 40831
URL: http://llvm.org/viewvc/llvm-project?rev=40831&view=rev
Log:
Make sure the good old "function/array conversion" is done to function parameters.
This resulted in the following error...
[dylan:clang/test/Parser] admin% cat parmvardecl_conversion.c
// RUN: clang -parse-ast-check %s
void f (int p[]) { p++; }
[dylan:clang/test/Parser] admin% clang -parse-ast-check parmvardecl_conversion.c
Errors seen but not expected:
Line 3: cannot modify value of type 'int []'
With this fix, the test case above succeeds.
Added:
cfe/trunk/test/Parser/parmvardecl_conversion.c
Modified:
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/Decl.h
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=40831&r1=40830&r2=40831&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Sat Aug 4 21:16:31 2007
@@ -73,7 +73,32 @@
return Diag(Loc, diag::err_undeclared_var_use, II.getName());
}
}
-
+ if (ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D)) {
+ // For ParmVarDecl's, we perform the default function/array conversion
+ // (C99 6.7.5.3p[7,8]).
+ QualType DeclRefType;
+ if (const ArrayType *AT = PD->getType()->getAsArrayType())
+ DeclRefType = Context.getPointerType(AT->getElementType());
+ else if (PD->getType()->isFunctionType())
+ DeclRefType = Context.getPointerType(PD->getType());
+ else
+ DeclRefType = PD->getType();
+ return new DeclRefExpr(PD, DeclRefType, Loc);
+ }
+ // The function/arrray conversion cannot be done for ValueDecl's in general.
+ // Consider this example:
+ //
+ // void func(int parmvardecl[5]) {
+ // int blockvardecl[5];
+ // sizeof(parmvardecl); // type is "int *" (converted from "int [5]")
+ // sizeof(blockvardecl); // type is "int [5]" (cannot convert to "int *")
+ // }
+ //
+ // If we converted blockvardecl (at this level) is would be be incorrect
+ // for the sizeof and address of (&) operators (see C99 6.3.2.1p[2-4]).
+ // This doesn't matter for parmvardecl, since arrays are always passed by
+ // reference (i.e. the [5] on parmvardecl is superfluous).
+ //
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D))
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=40831&r1=40830&r2=40831&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Aug 4 21:16:31 2007
@@ -198,7 +198,7 @@
ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
Decl *PrevDecl)
: VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
-
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
static bool classof(const ParmVarDecl *D) { return true; }
Added: cfe/trunk/test/Parser/parmvardecl_conversion.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/parmvardecl_conversion.c?rev=40831&view=auto
==============================================================================
--- cfe/trunk/test/Parser/parmvardecl_conversion.c (added)
+++ cfe/trunk/test/Parser/parmvardecl_conversion.c Sat Aug 4 21:16:31 2007
@@ -0,0 +1,4 @@
+// RUN: clang -parse-ast-check %s
+
+void f (int p[]) { p++; }
+
More information about the cfe-commits
mailing list