[cfe-commits] r92041 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/CodeGenCXX/rtti-linkage.cpp

Eli Friedman eli.friedman at gmail.com
Wed Dec 23 16:30:05 PST 2009


On Wed, Dec 23, 2009 at 3:25 PM, Douglas Gregor <dgregor at apple.com> wrote:
>
> On Dec 23, 2009, at 3:21 PM, Eli Friedman wrote:
>
>> On Wed, Dec 23, 2009 at 12:51 PM, Douglas Gregor <dgregor at apple.com>
>> wrote:
>>>
>>> Author: dgregor
>>> Date: Wed Dec 23 14:51:04 2009
>>> New Revision: 92041
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=92041&view=rev
>>> Log:
>>> Remove cv-qualifiers from the argument to typeid
>>>
>>> Modified:
>>>   cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>>   cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=92041&r1=92040&r2=92041&view=diff
>>>
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Dec 23 14:51:04 2009
>>> @@ -31,9 +31,14 @@
>>>  if (!StdNamespace)
>>>    return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
>>>
>>> -  if (isType)
>>> +  if (isType) {
>>> +    // C++ [expr.typeid]p4:
>>> +    //   The top-level cv-qualifiers of the lvalue expression or the
>>> type-id
>>> +    //   that is the operand of typeid are always ignored.
>>>    // FIXME: Preserve type source info.
>>> -    TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
>>> +    // FIXME: Preserve the type before we stripped the cv-qualifiers?
>>> +    TyOrExpr
>>> =GetTypeFromParser(TyOrExpr).getUnqualifiedType().getAsOpaquePtr();
>>> +  }
>>>
>>>  IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
>>>  LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
>>> @@ -45,21 +50,35 @@
>>>  QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
>>>
>>>  if (!isType) {
>>> -    // C++0x [expr.typeid]p3:
>>> -    //   When typeid is applied to an expression other than an lvalue of
>>> a
>>> -    //   polymorphic class type [...] [the] expression is an unevaluated
>>> -    //   operand.
>>> -
>>> -    // FIXME: if the type of the expression is a class type, the class
>>> -    // shall be completely defined.
>>>    bool isUnevaluatedOperand = true;
>>>    Expr *E = static_cast<Expr *>(TyOrExpr);
>>> -    if (E && !E->isTypeDependent() && E->isLvalue(Context) ==
>>> Expr::LV_Valid) {
>>> +    if (E && !E->isTypeDependent()) {
>>>      QualType T = E->getType();
>>>      if (const RecordType *RecordT = T->getAs<RecordType>()) {
>>>        CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
>>> -        if (RecordD->isPolymorphic())
>>> +        // C++ [expr.typeid]p3:
>>> +        //   When typeid is applied to an expression other than an
>>> lvalue of a
>>> +        //   polymorphic class type [...] [the] expression is an
>>> unevaluated
>>> +        //   operand. [...]
>>> +        if (RecordD->isPolymorphic() && E->isLvalue(Context) ==
>>> Expr::LV_Valid)
>>>          isUnevaluatedOperand = false;
>>> +        else {
>>> +          // C++ [expr.typeid]p3:
>>> +          //   [...] If the type of the expression is a class type, the
>>> class
>>> +          //   shall be completely-defined.
>>> +          // FIXME: implement this!
>>> +        }
>>> +      }
>>> +
>>> +      // C++ [expr.typeid]p4:
>>> +      //   [...] If the type of the type-id is a reference to a possibly
>>> +      //   cv-qualified type, the result of the typeid expression refers
>>> to a
>>> +      //   std::type_info object representing the cv-unqualified
>>> referenced
>>> +      //   type.
>>> +      if (T.hasQualifiers()) {
>>> +        ImpCastExprToType(E, T.getUnqualifiedType(), CastExpr::CK_NoOp,
>>> +                          E->isLvalue(Context));
>>> +        TyOrExpr = E;
>>>      }
>>>    }
>>
>> Umm, applying getUnqualifiedType to a non-canonical type?
>
> Yes, that works now; I fixed it a few weeks ago after seeing too many bugs
> where it did the wrong thing for non-canonical types. We desugar the type as
> far as we need to to find an unqualified type.

Hmm, but in this particular context, it'll screw up something like the
following:
#include <typeinfo>
typedef int A[10];
std::type_info a() { return typeid(const A); }

-Eli




More information about the cfe-commits mailing list