From 3292d5ce510061ea50152f53b7ab462b622176f4 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 7 Jul 2009 19:06:02 +0000 Subject: [PATCH] Some (most) type trait expressions require that the argument passed in is a complete type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74937 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ lib/Sema/SemaExprCXX.cpp | 20 +++++++++++++------- test/SemaCXX/type-traits-incomplete.cpp | 7 +++++++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 test/SemaCXX/type-traits-incomplete.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b1a73d05a4..32f2d51958 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1549,6 +1549,9 @@ def ext_typecheck_expression_not_constant_but_accepted : Extension< def warn_unused_expr : Warning<"expression result unused">, InGroup; +def err_incomplete_type_used_in_type_trait_expr : Error< + "incomplete type %0 used in type trait expression">; + // inline asm. def err_asm_wide_character : Error<"wide string is invalid in 'asm'">; def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 7afa5941da..b6c2d0521f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1023,17 +1023,23 @@ Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT, SourceLocation LParen, TypeTy *Ty, SourceLocation RParen) { - // FIXME: Some of the type traits have requirements. Interestingly, only the - // __is_base_of requirement is explicitly stated to be diagnosed. Indeed, G++ - // accepts __is_pod(Incomplete) without complaints, and claims that the type - // is indeed a POD. + QualType T = QualType::getFromOpaquePtr(Ty); + + // According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html + // all traits except __is_class, __is_enum and __is_union require a the type + // to be complete. + if (OTT != UTT_IsClass && OTT != UTT_IsEnum && OTT != UTT_IsUnion) { + if (RequireCompleteType(KWLoc, T, + diag::err_incomplete_type_used_in_type_trait_expr, + SourceRange(), SourceRange(), T)) + return ExprError(); + } // There is no point in eagerly computing the value. The traits are designed // to be used from type trait templates, so Ty will be a template parameter // 99% of the time. - return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, OTT, - QualType::getFromOpaquePtr(Ty), - RParen, Context.BoolTy)); + return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, OTT, T, + RParen, Context.BoolTy)); } QualType Sema::CheckPointerToMemberOperands( diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp new file mode 100644 index 0000000000..ac8ec452b9 --- /dev/null +++ b/test/SemaCXX/type-traits-incomplete.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct S; // expected-note{{forward declaration of 'struct S'}} + +void f() { + __is_pod(S); // expected-error{{incomplete type 'struct S' used in type trait expression}} +} -- 2.40.0