diff options
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 135 |
1 files changed, 104 insertions, 31 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index caa7b2f..e326a20 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -415,14 +415,19 @@ static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, } if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { - // Ignore empty strings without warnings - if (StrLit->getLength() == 0) + if (StrLit->getLength() == 0 || + StrLit->getString() == StringRef("*")) { + // Pass empty strings to the analyzer without warnings. + // Treat "*" as the universal lock. + Args.push_back(ArgExp); continue; + } // We allow constant strings to be used as a placeholder for expressions // that are not valid C++ syntax, but warn that they are ignored. S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << Attr.getName(); + Args.push_back(ArgExp); continue; } @@ -859,7 +864,6 @@ static void handleLockReturnedAttr(Sema &S, Decl *D, if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *Arg = Attr.getArg(0); if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) @@ -867,9 +871,6 @@ static void handleLockReturnedAttr(Sema &S, Decl *D, return; } - if (Arg->isTypeDependent()) - return; - // check that the argument is lockable object SmallVector<Expr*, 1> Args; checkAttrArgsAreLockableObjs(S, D, Attr, Args); @@ -962,7 +963,8 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { // If the alignment is less than or equal to 8 bits, the packed attribute // has no effect. - if (!FD->getType()->isIncompleteType() && + if (!FD->getType()->isDependentType() && + !FD->getType()->isIncompleteType() && S.Context.getTypeAlign(FD->getType()) <= 8) S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) << Attr.getName() << FD->getType(); @@ -973,8 +975,8 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (TagDecl *TD = dyn_cast<TagDecl>(D)) - TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); + if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) + RD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); else S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); } @@ -1522,6 +1524,20 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { Str->getString())); } +static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { + // Check the attribute arguments. + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) + << Attr.getName() << ExpectedFunctionOrMethod; + return; + } + + D->addAttr(::new (S.Context) MinSizeAttr(Attr.getRange(), S.Context)); +} + static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Check the attribute arguments. if (!checkAttributeNumArgs(S, Attr, 0)) @@ -2268,16 +2284,14 @@ static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { } if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { QualType T = TD->getUnderlyingType(); - if (!T->isPointerType() || - !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { + if (!T->isCARCBridgableType()) { S.Diag(TD->getLocation(), diag::err_nsobject_attribute); return; } } else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { QualType T = PD->getType(); - if (!T->isPointerType() || - !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { + if (!T->isCARCBridgableType()) { S.Diag(PD->getLocation(), diag::err_nsobject_attribute); return; } @@ -3583,7 +3597,12 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { } D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); + return; } + case AttributeList::AT_PnaclCall: + D->addAttr(::new (S.Context) PnaclCallAttr(Attr.getRange(), S.Context)); + return; + default: llvm_unreachable("unexpected attribute kind"); } @@ -3636,9 +3655,17 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { Diag(attr.getLoc(), diag::err_invalid_pcs); return true; } + case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break; default: llvm_unreachable("unexpected attribute kind"); } + const TargetInfo &TI = Context.getTargetInfo(); + TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); + if (A == TargetInfo::CCCR_Warning) { + Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); + CC = TI.getDefaultCallingConv(); + } + return false; } @@ -3878,11 +3905,11 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) returnType = MD->getResultType(); - else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) - returnType = PD->getType(); else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && (Attr.getKind() == AttributeList::AT_NSReturnsRetained)) return; // ignore: was handled as a type attribute + else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) + returnType = PD->getType(); else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) returnType = FD->getResultType(); else { @@ -3971,6 +3998,33 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); } +static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, + const AttributeList &attr) { + SourceLocation loc = attr.getLoc(); + ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); + + if (!method) { + S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) + << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; + return; + } + DeclContext *DC = method->getDeclContext(); + if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { + S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) + << attr.getName() << 0; + S.Diag(PDecl->getLocation(), diag::note_protocol_decl); + return; + } + if (method->getMethodFamily() == OMF_dealloc) { + S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) + << attr.getName() << 1; + return; + } + + method->addAttr( + ::new (S.Context) ObjCRequiresSuperAttr(attr.getRange(), S.Context)); +} + /// Handle cf_audited_transfer and cf_unknown_transfer. static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { if (!isa<FunctionDecl>(D)) { @@ -4149,19 +4203,21 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (S.LangOpts.MicrosoftExt) { - AttributeList::Kind Kind = Attr.getKind(); - if (Kind == AttributeList::AT_SingleInheritance) - D->addAttr( - ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context)); - else if (Kind == AttributeList::AT_MultipleInheritance) - D->addAttr( - ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context)); - else if (Kind == AttributeList::AT_VirtualInheritance) - D->addAttr( - ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context)); - } else + if (!S.LangOpts.MicrosoftExt) { S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); + return; + } + + AttributeList::Kind Kind = Attr.getKind(); + if (Kind == AttributeList::AT_SingleInheritance) + D->addAttr( + ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context)); + else if (Kind == AttributeList::AT_MultipleInheritance) + D->addAttr( + ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context)); + else if (Kind == AttributeList::AT_VirtualInheritance) + D->addAttr( + ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context)); } static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -4246,6 +4302,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ExtVectorType: handleExtVectorTypeAttr(S, scope, D, Attr); break; + case AttributeList::AT_MinSize: + handleMinSizeAttr(S, D, Attr); + break; case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break; case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break; case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break; @@ -4278,6 +4337,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ObjCReturnsInnerPointer: handleObjCReturnsInnerPointerAttr(S, D, Attr); break; + case AttributeList::AT_ObjCRequiresSuper: + handleObjCRequiresSuperAttr(S, D, Attr); break; + case AttributeList::AT_NSBridged: handleNSBridgedAttr(S, scope, D, Attr); break; @@ -4360,6 +4422,7 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ThisCall: case AttributeList::AT_Pascal: case AttributeList::AT_Pcs: + case AttributeList::AT_PnaclCall: handleCallConvAttr(S, D, Attr); break; case AttributeList::AT_OpenCLKernel: @@ -4774,18 +4837,25 @@ static bool isDeclDeprecated(Decl *D) { static void DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message, SourceLocation Loc, - const ObjCInterfaceDecl *UnknownObjCClass) { + const ObjCInterfaceDecl *UnknownObjCClass, + const ObjCPropertyDecl *ObjCPropery) { DeclarationName Name = D->getDeclName(); if (!Message.empty()) { S.Diag(Loc, diag::warn_deprecated_message) << Name << Message; S.Diag(D->getLocation(), isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at : diag::note_previous_decl) << Name; + if (ObjCPropery) + S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute) + << ObjCPropery->getDeclName() << 0; } else if (!UnknownObjCClass) { S.Diag(Loc, diag::warn_deprecated) << D->getDeclName(); S.Diag(D->getLocation(), isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at : diag::note_previous_decl) << Name; + if (ObjCPropery) + S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute) + << ObjCPropery->getDeclName() << 0; } else { S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name; S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); @@ -4800,16 +4870,19 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, DD.Triggered = true; DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc, - DD.getUnknownObjCClass()); + DD.getUnknownObjCClass(), + DD.getObjCProperty()); } void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, SourceLocation Loc, - const ObjCInterfaceDecl *UnknownObjCClass) { + const ObjCInterfaceDecl *UnknownObjCClass, + const ObjCPropertyDecl *ObjCProperty) { // Delay if we're currently parsing a declaration. if (DelayedDiagnostics.shouldDelayDiagnostics()) { DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, UnknownObjCClass, + ObjCProperty, Message)); return; } @@ -4817,5 +4890,5 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, // Otherwise, don't warn if our current context is deprecated. if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) return; - DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass); + DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty); } |