diff options
author | Jeffrey Yasskin <jyasskin@google.com> | 2011-01-27 19:17:54 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@google.com> | 2011-01-27 19:17:54 +0000 |
commit | b7ee2e5cc999a45ec4fd7b879477816714aabb7e (patch) | |
tree | 2b58dd1730b74027a41049fe7bc9234a92ba2fa5 | |
parent | 96554fd1aa7350498de8911fb6f303a9262e6ec0 (diff) |
Revert r124217 because it didn't catch the actual error case it was trying to
catch:
lock_guard(my_mutex);
declares a variable instead of creating a temporary.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124398 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/LanguageExtensions.html | 28 | ||||
-rw-r--r-- | include/clang/Basic/Attr.td | 5 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | include/clang/Sema/AttributeList.h | 1 | ||||
-rw-r--r-- | lib/Sema/AttributeList.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/forbid-temporaries.cpp | 50 |
8 files changed, 1 insertions, 112 deletions
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html index b2b3f3cde6..30c85ffcbd 100644 --- a/docs/LanguageExtensions.html +++ b/docs/LanguageExtensions.html @@ -25,7 +25,6 @@ td { <li><a href="#vectors">Vectors and Extended Vectors</a></li> <li><a href="#deprecated">Messages on <tt>deprecated</tt> and <tt>unavailable</tt> attributes</a></li> <li><a href="#attributes-on-enumerators">Attributes on enumerators</a></li> -<li><a href="#forbid-temporaries-attribute">Attribute to forbid temporaries of a type</a></li> <li><a href="#checking_language_features">Checks for Standard Language Features</a></li> <ul> <li><a href="#cxx_exceptions">C++ exceptions</a></li> @@ -343,33 +342,6 @@ individual enumerators.</p> <p>Query for this feature with <tt>__has_feature(enumerator_attributes)</tt>.</p> <!-- ======================================================================= --> -<h2 id="forbid-temporaries-attribute">Attribute to forbid temporaries of a type</h2> -<!-- ======================================================================= --> - -<p>Clang provides a <tt>forbid_temporaries</tt> attribute to forbid -temporaries of a particular type.</p> - -<blockquote> -<pre>class __attribute__((forbid_temporaries)) scoped_lock { - ... -};</pre> -</blockquote> - -<p>This prevents mistakes like</p> - -<blockquote> -<pre>void foo() { - scoped_lock(my_mutex); - // Forgot the local variable name, so destructor runs here. - code_that_needs_lock_held(); - // User expects destructor to run here. -};</pre> -</blockquote> - -<p>Query for this feature with <tt>__has_attribute(forbid_temporaries)</tt>. -Use <tt>-Wno-forbid-temporaries</tt> to disable the resulting warning.</p> - -<!-- ======================================================================= --> <h2 id="checking_language_features">Checks for Standard Language Features</h2> <!-- ======================================================================= --> diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 010736112d..9b0982a29b 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -232,11 +232,6 @@ def Final : InheritableAttr { let Spellings = []; } -def ForbidTemporaries : Attr { - let Spellings = ["forbid_temporaries"]; - let Subjects = [CXXRecord]; -} - def Format : InheritableAttr { let Spellings = ["format"]; let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index cb87f0d5e6..17bbc68afb 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -861,9 +861,6 @@ def err_temp_copy_deleted : Error< "of type %1 invokes deleted constructor">; def err_temp_copy_incomplete : Error< "copying a temporary object of incomplete type %0">; -def warn_temporaries_forbidden : Warning< - "must not create temporaries of type %0">, - InGroup<DiagGroup<"forbid-temporaries">>; // C++0x decltype def err_cannot_determine_declared_type_of_overloaded_function : Error< diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 7ed6ffcdaf..91389a4d98 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -104,7 +104,6 @@ public: AT_dllimport, AT_ext_vector_type, AT_fastcall, - AT_forbid_temporaries, AT_format, AT_format_arg, AT_global, diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index c3efda9a7a..77d962542b 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -85,7 +85,6 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { .Case("deprecated", AT_deprecated) .Case("visibility", AT_visibility) .Case("destructor", AT_destructor) - .Case("forbid_temporaries", AT_forbid_temporaries) .Case("format_arg", AT_format_arg) .Case("gnu_inline", AT_gnu_inline) .Case("weak_import", AT_weak_import) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 21d0f46528..474c7cb82f 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -885,24 +885,6 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); } -static void HandleForbidTemporariesAttr(Decl *d, const AttributeList &Attr, - Sema &S) { - assert(Attr.isInvalid() == false); - - if (Attr.getNumArgs() != 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; - return; - } - - if (!isa<TypeDecl>(d)) { - S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) - << Attr.getName() << 9 /*class*/; - return; - } - - d->addAttr(::new (S.Context) ForbidTemporariesAttr(Attr.getLoc(), S.Context)); -} - static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) @@ -2692,8 +2674,6 @@ static void ProcessInheritableDeclAttr(Scope *scope, Decl *D, case AttributeList::AT_ext_vector_type: HandleExtVectorTypeAttr(scope, D, Attr, S); break; - case AttributeList::AT_forbid_temporaries: - HandleForbidTemporariesAttr(D, Attr, S); break; case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8581c6f649..e95bad4d0a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3294,12 +3294,9 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { } } - CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - if (RD->getAttr<ForbidTemporariesAttr>()) - Diag(E->getExprLoc(), diag::warn_temporaries_forbidden) << E->getType(); - // That should be enough to guarantee that this type is complete. // If it has a trivial destructor, we can avoid the extra copy. + CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); if (RD->isInvalidDecl() || RD->hasTrivialDestructor()) return Owned(E); diff --git a/test/SemaCXX/forbid-temporaries.cpp b/test/SemaCXX/forbid-temporaries.cpp deleted file mode 100644 index cbe47aed5e..0000000000 --- a/test/SemaCXX/forbid-temporaries.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#if !__has_attribute(forbid_temporaries) -#error "Should support forbid_temporaries attribute" -#endif - -class __attribute__((forbid_temporaries)) NotATemporary { -}; - -class __attribute__((forbid_temporaries(1))) ShouldntHaveArguments { // expected-error {{attribute requires 0 argument(s)}} -}; - -void bad_function() __attribute__((forbid_temporaries)); // expected-warning {{'forbid_temporaries' attribute only applies to classes}} - -int var __attribute__((forbid_temporaries)); // expected-warning {{'forbid_temporaries' attribute only applies to classes}} - -void bar(const NotATemporary&); - -void foo() { - NotATemporary this_is_fine; - bar(NotATemporary()); // expected-warning {{must not create temporaries of type 'NotATemporary'}} - NotATemporary(); // expected-warning {{must not create temporaries of type 'NotATemporary'}} -} - - -// Check that the above restrictions work for templates too. -template<typename T> -class __attribute__((forbid_temporaries)) NotATemporaryTpl { -}; - -template<typename T> -void bar_tpl(const NotATemporaryTpl<T>&); - -void tpl_user() { - NotATemporaryTpl<int> this_is_fine; - bar_tpl(NotATemporaryTpl<int>()); // expected-warning {{must not create temporaries of type 'NotATemporaryTpl<int>'}} - NotATemporaryTpl<int>(); // expected-warning {{must not create temporaries of type 'NotATemporaryTpl<int>'}} -} - - -// Test that a specialization can override the template's default. -struct TemporariesOk; -template<> class NotATemporaryTpl<TemporariesOk> { -}; - -void specialization_user() { - NotATemporaryTpl<TemporariesOk> this_is_fine; - bar_tpl(NotATemporaryTpl<TemporariesOk>()); - NotATemporaryTpl<TemporariesOk>(); -} |