[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:33:55 PST 2009


On Wed, Dec 23, 2009 at 4:30 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> 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); }

Oops, umm, actually, it looks like we get that right, but mess up
"typeid(const int[10])".

-Eli




More information about the cfe-commits mailing list