diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AttributeList.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 5 |
3 files changed, 25 insertions, 1 deletions
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index 77d962542b..c3efda9a7a 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -85,6 +85,7 @@ 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 474c7cb82f..21d0f46528 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -885,6 +885,24 @@ 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) @@ -2674,6 +2692,8 @@ 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 0b7a051365..cb02be546e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3188,9 +3188,12 @@ 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); |