The RUN_CLANG_STATIC_ANALYZER ("Run Static Analyzer") project setting has found important issues in our project. We have addressed them and we want to prevent future issues from creeping in.
We're trying to get clang analysis warnings to be treated as errors to break our build. So far no success despite having -Werror ("Treat Warnings as Errors") enabled.
The following analysis call generated within Xcode:
/Developer/usr/bin/clang -x objective-c [...] --analyze [...]/TroubledCode.m -o [...]/TroubledTarget.build/StaticAnalyzer/normal/i386/TroubledCode.plist
produces a static code analysis warning:
[...]/TroubledCode.m:38:34: warning: Potential leak of an object allocated on line 38 and stored into 'leakingManager'
Manager *leakingManager = [[Manager alloc] init];
^
1 warning generated.
but Xcode reports "Build Succeeded ... 1 analyzer result". The solution we're looking for would make the example above generate a "Build Failed".
I took Jim's advice and created a build script.
To avoid false alarms, I went through the trouble of making sure it ignores extraneous analysis residue. This solution should work when building from the Xcode IDE and when building your project using xcodebuild
.
To turn Xcode 3 analysis warnings into build errors:
That setting is also known as LD_GENERATE_MAP_FILE
.
Copy the content below and paste it into the "Script" section.
error_count=0
##
function verify_clang_analysis_at_path()
{
local analysis_path=$1
local plist_tool=/usr/libexec/PlistBuddy
local diagnostics=$($plist_tool -c "print diagnostics" $analysis_path)
if [[ $diagnostics != $'Array {\n}' ]]
then
((error_count++))
fi
}
function verify_clang_analysis_for_object_file()
{
local object_file=$1
local analysis_directory=$TARGET_TEMP_DIR/StaticAnalyzer/$CURRENT_VARIANT/$CURRENT_ARCH
local analysis_path=$analysis_directory/${object_file%.*}.plist
# if this object file corresponds to a source file that clang analyzed...
if [ -e $analysis_path ]
then
verify_clang_analysis_at_path $analysis_path
fi
}
##
object_directory=$OBJECT_FILE_DIR-$CURRENT_VARIANT/$CURRENT_ARCH
object_path_pattern=${object_directory}'/\(.\)\+\.o$'
index_pattern='\[[[:space:]0-9]*\][[:space:]]'
object_paths=$(
grep $object_path_pattern $LD_MAP_FILE_PATH | sed s/$index_pattern//
)
##
for object_path in $object_paths
do
object_file=${object_path##*/}
verify_clang_analysis_for_object_file $object_file
done
if [ $error_count -gt 0 ]
then
echo "Clang static code analysis failed for" $error_count "source file(s)."
fi
exit $error_count
Mike Vosseller has an upgraded version of this script for Xcode 5.
We've been planning on having a separate build step to run the analyzer and check the results. We'll fail the build on the build server that way. That won't help you locally, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With