From: Bill Wendling Date: Tue, 17 Jul 2007 03:52:31 +0000 (+0000) Subject: Fix references: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08ad47cbd1f81fcb31dbc731c13b885a07e12704;p=clang Fix references: According to the spec (C++ 5p6[expr]), we need to adjust "T&" to "T" before further analysis. We do this via the "implicit cast" thingy. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39953 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Expr.cpp b/AST/Expr.cpp index 2edea9796d..7b8e1fdf5e 100644 --- a/AST/Expr.cpp +++ b/AST/Expr.cpp @@ -191,6 +191,7 @@ bool Expr::hasLocalSideEffect() const { /// - e->name /// - *e, the type of e cannot be a function type /// - string-constant +/// - reference type [C++ [expr]] /// Expr::isLvalueResult Expr::isLvalue() const { // first, check the type (C99 6.3.2.1) @@ -199,7 +200,10 @@ Expr::isLvalueResult Expr::isLvalue() const { if (TR->isIncompleteType() && TR->isVoidType()) return LV_IncompleteVoidType; - + + if (isa(TR.getCanonicalType())) // C++ [expr] + return LV_Valid; + // the type looks fine, now check the expression switch (getStmtClass()) { case StringLiteralClass: // C99 6.5.1p4 diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index f0d4ac2040..93a2df90aa 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -596,7 +596,9 @@ static void promoteExprToType(Expr *&expr, QualType type) { void Sema::DefaultFunctionArrayConversion(Expr *&e) { QualType t = e->getType(); assert(!t.isNull() && "DefaultFunctionArrayConversion - missing type"); - + + if (const ReferenceType *ref = dyn_cast(t.getCanonicalType())) + t = promoteExprToType(e, ref->getReferenceeType()); // C++ [expr] if (t->isFunctionType()) promoteExprToType(e, Context.getPointerType(t)); else if (const ArrayType *ary = dyn_cast(t.getCanonicalType())) @@ -612,6 +614,8 @@ void Sema::UsualUnaryConversions(Expr *&expr) { QualType t = expr->getType(); assert(!t.isNull() && "UsualUnaryConversions - missing type"); + if (const ReferenceType *ref = dyn_cast(t.getCanonicalType())) + t = promoteExprToType(expr, ref->getReferenceeType()); // C++ [expr] if (t->isPromotableIntegerType()) // C99 6.3.1.1p2 promoteExprToType(expr, Context.IntTy); else diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 47c36bbd5b..baa787dec8 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -61,6 +61,7 @@ public: /// - e->name /// - *e, the type of e cannot be a function type /// - string-constant + /// - reference type [C++ [expr]] /// enum isLvalueResult { LV_Valid, diff --git a/test/Sema/cxx-references.cpp b/test/Sema/cxx-references.cpp new file mode 100644 index 0000000000..785180d82a --- /dev/null +++ b/test/Sema/cxx-references.cpp @@ -0,0 +1,18 @@ +// RUN: clang -fsyntax-only %s +int g(int); + +void f() { + int i; + int &r = i; + r = 1; + int *p = &r; + int &rr = r; + int (&rg)(int) = g; + rg(i); + int a[3]; + int (&ra)[3] = a; + ra[1] = i; + int *Q; + int *& P = Q; + P[1] = 1; +}