diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:43 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:43 +0000 |
commit | fcded9b93a96e9a88405325b30caa4cd11120aee (patch) | |
tree | c06abf22140d0af2b7fe042a8be53f012ae1bb3e /clang/lib | |
parent | 22bfa2c28bdbca09949ba4cf8670c310d3e42c71 (diff) | |
download | bcm5719-llvm-fcded9b93a96e9a88405325b30caa4cd11120aee.tar.gz bcm5719-llvm-fcded9b93a96e9a88405325b30caa4cd11120aee.zip |
[objc] Emit warnings when the implementation of a designated initializer calls on
super an initializer that is not a designated one or any initializer on self.
llvm-svn: 196317
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 31 |
3 files changed, 32 insertions, 10 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index cb58ad482e1..b392e2f6619 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -655,12 +655,15 @@ bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { hasAttr<ObjCDesignatedInitializerAttr>(); } -bool ObjCMethodDecl::isDesignatedInitializerForTheInterface() const { +bool ObjCMethodDecl::isDesignatedInitializerForTheInterface( + const ObjCMethodDecl **InitMethod) const { + if (getMethodFamily() != OMF_init) + return false; const DeclContext *DC = getDeclContext(); if (isa<ObjCProtocolDecl>(DC)) return false; if (const ObjCInterfaceDecl *ID = getClassInterface()) - return ID->isDesignatedInitializer(getSelector()); + return ID->isDesignatedInitializer(getSelector(), InitMethod); return false; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c14cc4b8619..f243c0e8d18 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9816,8 +9816,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, } if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) { const ObjCMethodDecl *InitMethod = 0; - bool isDesignated = MD->getClassInterface() - ->isDesignatedInitializer(MD->getSelector(), &InitMethod); + bool isDesignated = + MD->isDesignatedInitializerForTheInterface(&InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Diag(MD->getLocation(), diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 20f4b4f7248..c4523064579 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -2447,14 +2447,33 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } - if (SuperLoc.isValid() && getCurFunction()->ObjCIsDesignatedInit) { - if (const ObjCObjectPointerType * - OCIType = ReceiverType->getAsObjCInterfacePointerType()) { - if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) { - if (ID->isDesignatedInitializer(Sel)) - getCurFunction()->ObjCWarnForNoDesignatedInitChain = false; + if (Method && Method->getMethodFamily() == OMF_init && + getCurFunction()->ObjCIsDesignatedInit && + (SuperLoc.isValid() || isSelfExpr(Receiver))) { + bool isDesignatedInitChain = false; + if (SuperLoc.isValid()) { + if (const ObjCObjectPointerType * + OCIType = ReceiverType->getAsObjCInterfacePointerType()) { + if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) { + if (ID->isDesignatedInitializer(Sel)) { + isDesignatedInitChain = true; + getCurFunction()->ObjCWarnForNoDesignatedInitChain = false; + } + } } } + if (!isDesignatedInitChain) { + const ObjCMethodDecl *InitMethod = 0; + bool isDesignated = + getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod); + assert(isDesignated && InitMethod); + (void)isDesignated; + Diag(SelLoc, SuperLoc.isValid() ? + diag::warn_objc_designated_init_non_designated_init_call : + diag::warn_objc_designated_init_non_super_designated_init_call); + Diag(InitMethod->getLocation(), + diag::note_objc_designated_init_marked_here); + } } // Check the message arguments. |