clang
20.0.0git
lib
StaticAnalyzer
Checkers
CheckObjCInstMethSignature.cpp
Go to the documentation of this file.
1
//===-- CheckObjCInstMethSignature.cpp - Check ObjC method signatures -----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines a CheckObjCInstMethSignature, a flow-insensitive check
10
// that determines if an Objective-C class interface incorrectly redefines
11
// the method signature in a subclass.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "
clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
"
16
#include "
clang/Analysis/PathDiagnostic.h
"
17
#include "
clang/AST/ASTContext.h
"
18
#include "
clang/AST/DeclObjC.h
"
19
#include "
clang/AST/Type.h
"
20
#include "
clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
"
21
#include "
clang/StaticAnalyzer/Core/Checker.h
"
22
#include "llvm/ADT/DenseMap.h"
23
#include "llvm/Support/raw_ostream.h"
24
25
using namespace
clang
;
26
using namespace
ento;
27
28
static
bool
AreTypesCompatible
(
QualType
Derived,
QualType
Ancestor,
29
ASTContext
&
C
) {
30
31
// Right now don't compare the compatibility of pointers. That involves
32
// looking at subtyping relationships. FIXME: Future patch.
33
if
(Derived->
isAnyPointerType
() && Ancestor->
isAnyPointerType
())
34
return
true
;
35
36
return
C
.typesAreCompatible(Derived, Ancestor);
37
}
38
39
static
void
CompareReturnTypes
(
const
ObjCMethodDecl
*MethDerived,
40
const
ObjCMethodDecl
*MethAncestor,
41
BugReporter
&BR,
ASTContext
&Ctx,
42
const
ObjCImplementationDecl
*ID,
43
const
CheckerBase
*
Checker
) {
44
45
QualType
ResDerived = MethDerived->
getReturnType
();
46
QualType
ResAncestor = MethAncestor->
getReturnType
();
47
48
if
(!
AreTypesCompatible
(ResDerived, ResAncestor, Ctx)) {
49
std::string sbuf;
50
llvm::raw_string_ostream os(sbuf);
51
52
os <<
"The Objective-C class '"
53
<< *MethDerived->
getClassInterface
()
54
<<
"', which is derived from class '"
55
<< *MethAncestor->
getClassInterface
()
56
<<
"', defines the instance method '"
;
57
MethDerived->
getSelector
().
print
(os);
58
os <<
"' whose return type is '"
<< ResDerived
59
<<
"'. A method with the same name (same selector) is also defined in "
60
"class '"
61
<< *MethAncestor->
getClassInterface
() <<
"' and has a return type of '"
62
<< ResAncestor
63
<<
"'. These two types are incompatible, and may result in undefined "
64
"behavior for clients of these classes."
;
65
66
PathDiagnosticLocation
MethDLoc =
67
PathDiagnosticLocation::createBegin
(MethDerived,
68
BR.
getSourceManager
());
69
70
BR.
EmitBasicReport
(
71
MethDerived,
Checker
,
"Incompatible instance method return type"
,
72
categories::CoreFoundationObjectiveC
, os.str(), MethDLoc);
73
}
74
}
75
76
static
void
CheckObjCInstMethSignature
(
const
ObjCImplementationDecl
*ID,
77
BugReporter
&BR,
78
const