From c0959b173b1358ce8b4e3e02c3cd9166186b1f2e Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Mon, 20 Aug 2018 00:06:45 +0430 Subject: fixes #47. probably a good idea to just wipe and re-clone. also moved m0 to its own folder. --- bruiser/bruiser.cpp | 2 +- bruiser/lua-5.3.4/Makefile | 2 +- bruiser/lua-5.3.4/src/Makefile | 4 +- bruiser/luatablegen/makefile | 25 +- bruiser/makefile | 30 +- compile_commands.json | 57 - daemon/makefile | 113 +- json/makefile | 19 +- m0/makefile | 187 + m0/mutator-lvl0.cpp | 8710 ++++++++++++++++++++++++++++++++++++++++ m0/mutator-lvl0.h | 542 +++ m0/mutator-lvl1.cpp | 622 +++ m0/mutator-lvl2.cpp | 120 + m0/mutator_aux.cpp | 151 + m0/mutator_aux.h | 66 + m0/mutator_report.cpp | 314 ++ m0/mutator_report.h | 117 + makefile | 55 +- mutator-lvl0.cpp | 8710 ---------------------------------------- mutator-lvl0.h | 542 --- mutator-lvl1.cpp | 622 --- mutator-lvl2.cpp | 120 - mutator_aux.cpp | 152 - mutator_aux.h | 76 - mutator_report.cpp | 314 -- mutator_report.h | 117 - obfuscator/makefile | 33 +- obfuscator/obfuscator.cpp | 2 +- safercpp/makefile | 166 +- safercpp/safercpp-arr.cpp | 2 +- tinyxml2/makefile | 17 +- 31 files changed, 11173 insertions(+), 10836 deletions(-) delete mode 100644 compile_commands.json create mode 100644 m0/makefile create mode 100644 m0/mutator-lvl0.cpp create mode 100644 m0/mutator-lvl0.h create mode 100644 m0/mutator-lvl1.cpp create mode 100644 m0/mutator-lvl2.cpp create mode 100644 m0/mutator_aux.cpp create mode 100644 m0/mutator_aux.h create mode 100644 m0/mutator_report.cpp create mode 100644 m0/mutator_report.h delete mode 100644 mutator-lvl0.cpp delete mode 100644 mutator-lvl0.h delete mode 100644 mutator-lvl1.cpp delete mode 100644 mutator-lvl2.cpp delete mode 100644 mutator_aux.cpp delete mode 100644 mutator_aux.h delete mode 100644 mutator_report.cpp delete mode 100644 mutator_report.h diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index e47d37c..65564b4 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* /*project headers*/ #include "bruiser.h" #include "CompletionHints.h" -#include "../mutator_aux.h" +#include "../m0/mutator_aux.h" #include "mutagen.h" #include "ORCmutation.h" #include "executioner.h" diff --git a/bruiser/lua-5.3.4/Makefile b/bruiser/lua-5.3.4/Makefile index 119110d..e97f52a 100644 --- a/bruiser/lua-5.3.4/Makefile +++ b/bruiser/lua-5.3.4/Makefile @@ -4,7 +4,7 @@ # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. -PLAT= none +PLAT= linux # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. See the local target. diff --git a/bruiser/lua-5.3.4/src/Makefile b/bruiser/lua-5.3.4/src/Makefile index 0eb167f..202d0c9 100644 --- a/bruiser/lua-5.3.4/src/Makefile +++ b/bruiser/lua-5.3.4/src/Makefile @@ -4,7 +4,7 @@ # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= # Your platform. See PLATS for possible values. -PLAT= none +PLAT= linux CC= gcc -std=gnu99 CFLAGS= -fpic -O2 -Wall -Wextra -DLUA_COMPAT_MODULE -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) @@ -49,7 +49,7 @@ ALL_A= $(LUA_A) # Targets start here. default: $(PLAT) -all: $(ALL_T) +all: $(ALL_A) o: $(ALL_O) diff --git a/bruiser/luatablegen/makefile b/bruiser/luatablegen/makefile index 472c591..b59a216 100644 --- a/bruiser/luatablegen/makefile +++ b/bruiser/luatablegen/makefile @@ -1,16 +1,25 @@ CC=clang CC?=clang -CC_FLAGS=$(shell $(PY_CONF) --includes) -fpic +CC_FLAGS=-fpic CC_EXTRA?= CC_FLAGS+=$(CC_EXTRA) SRCS=$(wildcard *.c) TBG_OBJLIST=$(patsubst %.c, %.o , $(wildcard *.c)) +TBG_OBJLIST_DBG=$(patsubst %.c, %.odbg , $(wildcard *.c)) +TBG_OBJLIST_COV=$(patsubst %.c, %.ocov , $(wildcard *.c)) +ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer +ADD_SANITIZERS_LD= -g -fsanitize=address +MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer +MEM_SANITIZERS_LD= -g -fsanitize=memory +UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer +UB_SANITIZERS_LD= -g -fsanitize=undefined +COV_CC= -fprofile-instr-generate -fcoverage-mapping .DEFAULT:all .PHONY:all clean help -all:$(TBG_OBJLIST) +all:$(TBG_OBJLIST) $(TBG_OBJLIST_DBG) $(TBG_OBJLIST_COV) @echo $(TBG_OBJLIST) @echo $(TBG_OBJLIST_INC) @@ -19,14 +28,22 @@ depend:.depend .depend:$(SRCS) rm -rf .depend $(CC) -MM $(CC_FLAGS) $^ > ./.depend + echo $(patsubst %.o:, %.odbg:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.ocov:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend -include ./.depend .c.o: - $(CC) $(CC_FLAGS) -c $< -o $@ + $(CC) $(CC_FLAGS) -c $< -o $@ + +%.odbg:%.c + $(CC) $(CC_FLAGS) -g -c $< -o $@ + +%.ocov:%.c + $(CC) $(CC_FLAGS) $(COV_CC) -c $< -o $@ clean: - rm -f *.o *~ $(TARGET) + rm -f *.o *~ $(TARGET) *.ocov *.odbg rm .depend help: diff --git a/bruiser/makefile b/bruiser/makefile index a5194c0..4a61d66 100644 --- a/bruiser/makefile +++ b/bruiser/makefile @@ -72,8 +72,10 @@ SRCS:=$(wildcard *.cpp) C_SRCS:=$(wildcard *.c) CXX_FLAGS+=$(CXX_EXTRA) EXTRA_LD_FLAGS+=$(shell $(PY_CONF) --ldflags) -lffi -lcapstone -lkeystone -L./lua-5.3.4/src -llua -TBG_OBJLIST_INC=$(patsubst ./luatablegen/%.c, ./luatablegen/%.o, $(wildcard ./luatablegen/*.c)) LD_FLAGS+=$(EXTRA_LD_FLAGS) +TBG_OBJLIST_INC=$(patsubst ./luatablegen/%.c, ./luatablegen/%.o, $(wildcard ./luatablegen/*.c)) +TBG_OBJLIST_DBG_INC=$(patsubst ./luatablegen/%.c, ./luatablegen/%.odbg, $(wildcard ./luatablegen/*.c)) +TBG_OBJLIST_COV_INC=$(patsubst ./luatablegen/%.c, ./luatablegen/%.ocov, $(wildcard ./luatablegen/*.c)) .DEFAULT:all @@ -104,11 +106,17 @@ dependc:.dependc .c.o: $(CC) $(CC_FLAGS) -c $< -o $@ +%.ocov:%.c + $(CC) $(CC_FLAGS) $(COV_CXX) -c $< -o $@ + +%.odbg:%.c + $(CC) $(CC_FLAGS) -g -c $< -o $@ + .cpp.o: $(CXX) $(CXX_FLAGS) -c $< -o $@ -../mutator_aux.o:../mutator_aux.cpp - $(CXX) $(CXX_FLAGS) -c $< -o $@ +#../mutator_aux.o:../mutator_aux.cpp + #$(CXX) $(CXX_FLAGS) -c $< -o $@ linenoise.o: $(CC) $(CC_FLAGS) linenoise/linenoise.c -c -o linenoise.o @@ -123,7 +131,7 @@ linenoise.o: $(MAKE) -C luatablegen $(LIB_LUA): - $(MAKE) -C lua-5.3.4/src linux a + $(MAKE) -C lua-5.3.4/src linux %.odbg:%.cpp $(CXX) $(CXX_FLAGS) -g -c $< -o $@ @@ -131,16 +139,17 @@ $(LIB_LUA): %.ocov:%.cpp $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ -$(TARGET): $(TARGET).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +$(TARGET): $(TARGET).o ../m0/mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) $(CXX) $^ $(LD_FLAGS) -o $@ -$(TARGET)-static: $(TARGET).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +# currently broken since it needs a static libpython +$(TARGET)-static: $(TARGET).o ../m0/mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) $(CXX) $^ $(LD_FLAGS) -static -o $@ -$(TARGET)-dbg: $(TARGET).odbg ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +$(TARGET)-dbg: $(TARGET).odbg ../m0/mutator_aux.odbg ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.odbg mutagen.o ORCmutation.o bruiserffi.odbg asmrewriter.odbg bruisercapstone.odbg ramdump.odbg ffs.odbg $(LIB_LUA) $(TBG_OBJLIST_DBG_INC) $(CXX) $^ $(LD_FLAGS) -g -o $@ -$(TARGET)-cov: $(TARGET).ocov ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +$(TARGET)-cov: $(TARGET).ocov ../m0/mutator_aux.ocov ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.ocov mutagen.o ORCmutation.o bruiserffi.ocov asmrewriter.ocov bruisercapstone.ocov ramdump.ocov ffs.ocov $(LIB_LUA) $(TBG_OBJLIST_COV_INC) $(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ cov: @@ -168,10 +177,10 @@ tags:$(SRCS) %.dis: %.o objdump -r -d -M intel -S $< > $@ -$(TARGET).so: $(TARGET).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +$(TARGET).so: $(TARGET).o ../m0/mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) $(CXX) $^ $(LD_FLAGS) -shared -o $@ -$(TARGET).a: $(TARGET).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) +$(TARGET).a: $(TARGET).o ../m0/mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o asmrewriter.o bruisercapstone.o ramdump.o ffs.o $(LIB_LUA) $(TBG_OBJLIST_INC) ar rcs $(TARGET).a $(TARGET).o clean: @@ -182,7 +191,6 @@ deepclean: rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so tags $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov FILE*.cpp FILE*.hpp rm .depend $(MAKE) -C lua-5.3.4 clean - $(MAKE) -C LuaJIT clean $(MAKE) -C luatablegen clean help: diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index 99561f1..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,57 +0,0 @@ -[ - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o mutator-lvl0.o mutator-lvl0.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/mutator-lvl0.cpp" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o tinyxml2.o tinyxml2.cpp", - "directory": "/home/bloodstalker/devi/hell2/tinyxml2", - "file": "/home/bloodstalker/devi/hell2/tinyxml2/tinyxml2.cpp" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o mutator_aux.o mutator_aux.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/mutator_aux.cpp" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o mutator_report.o mutator_report.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/mutator_report.cpp" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o mutator-lvl1.o mutator-lvl1.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/mutator-lvl1.cpp" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o mutator-lvl2.o mutator-lvl2.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/mutator-lvl2.cpp" - }, - { - "command": "cc -c -o mutatorclient.o mutatorclient.c", - "directory": "/home/bloodstalker/devi/hell2/daemon", - "file": "/home/bloodstalker/devi/hell2/daemon/mutatorclient.c" - }, - { - "command": "cc -c -o mutatord.o mutatord.c", - "directory": "/home/bloodstalker/devi/hell2/daemon", - "file": "/home/bloodstalker/devi/hell2/daemon/mutatord.c" - }, - { - "command": "cc -c -o daemon_aux.o daemon_aux.c", - "directory": "/home/bloodstalker/devi/hell2/daemon", - "file": "/home/bloodstalker/devi/hell2/daemon/daemon_aux.c" - }, - { - "command": "cc -c -o mutatorserver.o mutatorserver.c", - "directory": "/home/bloodstalker/devi/hell2/daemon", - "file": "/home/bloodstalker/devi/hell2/daemon/mutatorserver.c" - }, - { - "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o safercpp/safercpp-arr.o safercpp/safercpp-arr.cpp", - "directory": "/home/bloodstalker/devi/hell2", - "file": "/home/bloodstalker/devi/hell2/safercpp/safercpp-arr.cpp" - } -] \ No newline at end of file diff --git a/daemon/makefile b/daemon/makefile index 2fac344..8db570e 100644 --- a/daemon/makefile +++ b/daemon/makefile @@ -1,30 +1,77 @@ - -##################################VARS################################# CC=clang -CC_FLAGS= +CC?=clang +SHELL=bash +SHELL?=bash +CC_FLAGS=-fpic LD_FLAGS= TARGETD=mutatord TARGETS=mutatorserver TARGETC=mutatorclient -SRCS=$(wildcard *.c) -##################################RULES################################ +COV_CC= -fprofile-instr-generate -fcoverage-mapping +COV_LD= -fprofile-instr-generate +SRCS:=$(wildcard *.c) +OBJ_LIST:=$(patsubst %.c, %.o, $(wildcard *.c)) +ASM_LIST:=$(patsubst %.c, %.dis, $(wildcard *.c)) +CTAGS_I_PATH?=./ + +ifeq ($(BUILD_MODE), ADDSAN) +ifeq ($(CC), gcc) +$(error This build mode is only useable with clang.) +endif +CC_EXTRA+=$(ADD_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), MEMSAN) +ifeq ($(CC), gcc) +$(error This build mode is only useable with clang.) +endif +CC_EXTRA+=$(MEM_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), UBSAN) +ifeq ($(CC), gcc) +$(error This build mode is only useable with clang.) +endif +CC_EXTRA+=$(UB_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD) +endif + +CC_FLAGS+=$(CC_EXTRA) +LD_FLAGS+=$(EXTRA_LD_FLAGS) + .DEFAULT:all -.PHONY:all clean help depend +.PHONY:all clean help all:$(TARGETC) $(TARGETS) $(TARGETD) +everything: $(TARGETC) $(TARGETD) $(TARGETS) $(TARGETC)-dbg $(TARGETD)-dbg $(TARGETS)-dbg $(TARGETC)-cov $(TARGETD)-cov $(TARGETS)-cov ASM TAGS $(TARGETC)-static $(TARGETD)-static $(TARGETS)-static + depend:.depend .depend:$(SRCS) - rm -f ./.depend + rm -rf .depend $(CC) -MM $(CC_FLAGS) $^ > ./.depend + echo $(patsubst %.o:, %.odbg:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.ocov:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend -include .depend +ASM: $(ASM_LIST) + +TAGS: tags + .c.o: $(CC) $(CC_FLAGS) -c $< -o $@ +%.odbg:%.c + $(CC) $(CC_FLAGS) -g -c $< -o $@ + +%.ocov:%.c + $(CC) $(CC_FLAGS) $(COV_CC) -c $< -o $@ + $(TARGETC): $(TARGETC).o $(CC) $^ $(LD_FLAGS) -o $@ @@ -34,15 +81,57 @@ $(TARGETS): $(TARGETS).o daemon_aux.o $(TARGETD): $(TARGETD).o daemon_aux.o $(CC) $^ $(LD_FLAGS) -o $@ +$(TARGETC)-dbg: $(TARGETC).odbg + $(CC) $^ $(LD_FLAGS) -o $@ + +$(TARGETS)-dbg: $(TARGETS).odbg daemon_aux.odbg + $(CC) $^ $(LD_FLAGS) -o $@ + +$(TARGETD)-dbg: $(TARGETS).odbg daemon_aux.odbg + $(CC) $^ $(LD_FLAGS) -o $@ + +$(TARGETC)-cov: $(TARGETC).ocov + $(CC) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +$(TARGETS)-cov: $(TARGETS).ocov daemon_aux.ocov + $(CC) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +$(TARGETD)-cov: $(TARGETD).ocov daemon_aux.ocov + $(CC) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +$(TARGETC)-static: $(TARGETC).o + $(CC) $^ $(LD_FLAGS) -static -o $@ + +$(TARGETS)-static: $(TARGETS).o daemon_aux.o + $(CC) $^ $(LD_FLAGS) -static -o $@ + +$(TARGETD)-static: $(TARGETD).o daemon_aux.o + $(CC) $^ $(LD_FLAGS) -static -o $@ + +%.dis: %.o + objdump -r -d -M intel -S $< > $@ + +tags:$(SRCS) + $(shell $(CC) -c -I $(CTAGS_I_PATH) -M $(SRCS)|\ + sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\ + ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q) + +cov: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov show $(TARGET)-cov -instr-profile=default.profdata + +covrep: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov report $(TARGET)-cov -instr-profile=default.profdata + clean: - rm -f *.o *~ $(TARGETD) $(TARGETS) $(TARGETC) rm ./.depend + rm -f *.o *~ $(TARGETD) $(TARGETS) $(TARGETC) *.ocov *.odbg $(TARGETD)-cov $(TARGETC)-cov $(TARGETS)-cov $(TARGETD)-dbg $(TARGETC)-dbg $(TARGETS)-dbg tags $(TARGETD)-static $(TARGETC)-static $(TARGETS)-static help: @echo 'all builds the daemon, the server and the client. all is the default.' @echo 'mutatord builds the daemon with the server' @echo 'mutatorc builds the client' - @echo 'mutators builds the standalone server' - @echo 'clean runs clean.' - @echo 'help runs help.' - + @echo 'mutators builds the standalone server(deprecated)' + @echo 'clean' + @echo 'help' diff --git a/json/makefile b/json/makefile index 9f02064..15e3604 100644 --- a/json/makefile +++ b/json/makefile @@ -1,16 +1,19 @@ -######################################INCLUDES################################# include ../macros.mk +COV_CXX= -fprofile-instr-generate -fcoverage-mapping -############################################################################### +.DEFAULT: json.o -####################################RULES###################################### -.DEFAULT: json - -.PHONY: json +everything: json.o json.ocov json.odbg json.o: json.hpp - $(CXX) $(CXX_FLAGS) -c $< -o $@ + $(CXX) $(CXX_FLAGS) -x c++ -c $< -o $@ + +json.odbg: json.hpp + $(CXX) $(CXX_FLAGS) -x c++ -g -c $< -o $@ + +json.ocov: json.hpp + $(CXX) $(CXX_FLAGS) $(COV_CXX) -x c++ -c $< -o $@ clean: - rm -f *.o + rm -f *.o *.odbg *.ocov diff --git a/m0/makefile b/m0/makefile new file mode 100644 index 0000000..f1f9cb2 --- /dev/null +++ b/m0/makefile @@ -0,0 +1,187 @@ +TARGET=mutator-lvl0 +SHELL=bash +SHELL?=bash +CC=clang +CC?=clang +CFLAGS=-fpic -std=c11 +CXX=clang++ +CXX?=clang++ +CXX_FLAGS=-fpic +CXX_EXTRA?= +CTAGS_I_PATH?=./ +LD_FLAGS= +EXTRA_LD_FLAGS?= +ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer +ADD_SANITIZERS_LD= -g -fsanitize=address +MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer +MEM_SANITIZERS_LD= -g -fsanitize=memory +UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer +UB_SANITIZERS_LD= -g -fsanitize=undefined +COV_CXX= -fprofile-instr-generate -fcoverage-mapping +COV_LD= -fprofile-instr-generate +# BUILD_MODES are=RELEASE(default), DEBUG,ADDSAN,MEMSAN,UBSAN +BUILD_MODE?=RELEASE +OBJ_LIST:=$(patsubst %.cpp, %.o, $(wildcard *.cpp)) +ASM_LIST:=$(patsubst %.cpp, %.dis, $(wildcard *.cpp)) + +LLVM_CONF?=llvm-config +LLVM_CXX_FLAGS=$(shell $(LLVM_CONF) --cxxflags) +LLVM_CXX_FLAGS+=-I$(shell $(LLVM_CONF) --src-root)/tools/clang/include\ + -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include\ + -stdlib=libstdc++ -std=c++17 -fexceptions +LLVM_LD_FLAGS=-Wl,--start-group -lclangAST -lclangAnalysis -lclangBasic\ + -lclangDriver -lclangEdit -lclangFrontend -lclangFrontendTool\ + -lclangLex -lclangParse -lclangSema -lclangEdit -lclangASTMatchers\ + -lclangRewrite -lclangRewriteFrontend -lclangStaticAnalyzerFrontend\ + -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore\ + -lclangSerialization -lclangToolingCore -lclangTooling -lstdc++\ + -lLLVMRuntimeDyld -lm -Wl,--end-group +LLVM_LD_FLAGS+=$(shell $(LLVM_CONF) --ldflags --libs --system-libs) + +CXX_FLAGS+=$(LLVM_CXX_FLAGS) +LD_FLAGS+=$(LLVM_LD_FLAGS) + +MAKEFLAGS+=--warn-undefined-variables +ifeq ($(BUILD_MODE), ADDSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(ADD_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), MEMSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(MEM_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), UBSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(UB_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD) +endif + +SRCS:=$(wildcard *.cpp) +CXX_FLAGS+=$(CXX_EXTRA) +LD_FLAGS+=$(EXTRA_LD_FLAGS) + +.DEFAULT:all + +.PHONY:all clean help ASM SO TAGS + +all:$(TARGET) + +everything:$(TARGET) A ASM SO $(TARGET)-dbg TAGS $(TARGET)-cov + +depend:.depend + +.depend:$(SRCS) + rm -rf .depend + $(CXX) -MM $(CXX_FLAGS) $^ > ./.depend + echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\_\-]+\.odbg/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\_\-]+\.ocov/\n&/g' >> ./.depend + +-include ./.depend + +../json/json.o:../json/json.hpp + $(MAKE) -C ../json json.o + +../json/json.odbg:../json/json.hpp + $(MAKE) -C ../json json.odbg + +../json/json.ocov:../json/json.hpp + $(MAKE) -C ../json json.ocov + +../tinyxml2/tinyxml2.o:../tinyxml2/tinyxml2.cpp + $(MAKE) -C ../tinyxml2 tinyxml2.o + +../tinyxml2/tinyxml2.odbg:../tinyxml2/tinyxml2.cpp + $(MAKE) -C ../tinyxml2 tinyxml2.odbg + +../tinyxml2/tinyxml2.ocov:../tinyxml2/tinyxml2.cpp + $(MAKE) -C ../tinyxml2 tinyxml2.ocov + +./keccak-tiny/.o:./keccak-tiny/.c + $(CC) $(CFLAGS) -c $< -o $@ + +.cpp.o: + $(CXX) $(CXX_FLAGS) -c $< -o $@ + +%.odbg:%.cpp + $(CXX) $(CXX_FLAGS) -g -c $< -o $@ + +%.ocov:%.cpp + $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ + +$(TARGET): $(TARGET).o ../tinyxml2/tinyxml2.o ./mutator_aux.o ./mutator_report.o ../json/json.o + $(CXX) $^ $(LD_FLAGS) -o $@ + +$(TARGET)-static: $(TARGET).o ../tinyxml2/tinyxml2.o ./mutator_aux.o ./mutator_report.o ../json/json.o + $(CXX) $^ $(LD_FLAGS) -static -o $@ + +$(TARGET)-dbg: $(TARGET).odbg ../tinyxml2/tinyxml2.odbg ./mutator_aux.odbg ./mutator_report.odbg ../json/json.odbg + $(CXX) $^ $(LD_FLAGS) -g -o $@ + +$(TARGET)-cov: $(TARGET).ocov ../tinyxml2/tinyxml2.ocov ./mutator_aux.ocov ./mutator_report.ocov ../json/json.ocov + $(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +cov: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov show $(TARGET)-cov -instr-profile=default.profdata + +covrep: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov report $(TARGET)-cov -instr-profile=default.profdata + +ASM:$(ASM_LIST) + +SO:$(TARGET).so + +A:$(TARGET).a + +TAGS:tags + +tags:$(SRCS) + $(shell $(CXX) -c $(shell $(LLVM_CONF) --cxxflags) -I$(shell $(LLVM_CONF) --src-root)/tools/clang/include -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include -I $(CTAGS_I_PATH) -M $(SRCS)|\ + sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\ + ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q) + +%.dis: %.o + objdump -r -d -M intel -S $< > $@ + +$(TARGET).so: $(TARGET).o ../tinyxml2/tinyxml2.o ./mutator_aux.o ./mutator_report.o ../json/json.o + $(CXX) $^ $(LD_FLAGS) -shared -o $@ + +$(TARGET).a: $(TARGET).o ../tinyxml2/tinyxml2.o ./mutator_aux.o ./mutator_report.o ../json/json.o + ar rcs $(TARGET).a $(TARGET).o + +clean: + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov ./keccak-tiny/*.o + +deepclean: + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so tags $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov FILE*.cpp FILE*.hpp ./keccak-tiny/*.o + rm .depend + $(MAKE) -C ../tinyxml2 clean + $(MAKE) -C ../json clean + +help: + @echo "--all is the default target, runs $(TARGET) target" + @echo "--everything will build everything" + @echo "--SO will generate the so" + @echo "--ASM will generate assembly files" + @echo "--TAGS will generate tags file" + @echo "--$(TARGET) builds the dynamically-linked executable" + @echo "--$(TARGET)-dbg will generate the debug build. BUILD_MODE should be set to DEBUG to work" + @echo "--$(TARGET)-static will statically link the executable to the libraries" + @echo "--$(TARGET)-cov is the coverage build" + @echo "--cov will print the line coverage report" + @echo "--covrep will print the coverage report" + @echo "--A will build the static library" + @echo "--TAGS will build the tags file" + @echo "--clean" + @echo "--deepclean will clean almost everything" diff --git a/m0/mutator-lvl0.cpp b/m0/mutator-lvl0.cpp new file mode 100644 index 0000000..53b3ac5 --- /dev/null +++ b/m0/mutator-lvl0.cpp @@ -0,0 +1,8710 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*the source code for the static checks(Misra-C,...)*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ +/**********************************************************************************************************************/ +/*included modules*/ +/*project headers*/ +#include "mutator-lvl0.h" +#include "mutator_aux.h" +#include "mutator_report.h" +/*standard headers*/ +#include +#include +#include +#include +#include +#include +#include +#include +/*Clang headers*/ +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/MacroArgs.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Tooling/CommonOptionsParser.h" +//#include "clang/Tooling/Core/QualTypeNames.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Rewrite/Core/Rewriter.h" +/*LLVM headers*/ +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/APInt.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/Function.h" +/**********************************************************************************************************************/ +/*used namespaces*/ +using namespace llvm; +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::driver; +using namespace clang::tooling; +/**********************************************************************************************************************/ +/*macros and defs*/ + +/*@DEVI-disbale debugs info printouts.*/ +#define _MUT0_TEST +#if 1 +#undef _MUT0_TEST +#endif + +/*@DEVI-disbale all matchers.*/ +#define _MUT0_EN_MATCHERS +#if 0 +#undef _MUT0_EN_MATCHERS +#endif +/**********************************************************************************************************************/ +/*global vars*/ +Devi::XMLReport XMLDocOut; +Devi::JSONReport JSONDocOUT; +MutagenExtraction ME; + +std::vector MacroDefSourceLocation; +std::vector MacroUndefSourceLocation; +std::vector MacroNameString; +std::vector IncludeFileArr; + +/**********************************************************************************************************************/ +struct MutExHeaderNotFound : public std::exception +{ +public: + MutExHeaderNotFound(std::string FileName) : FName(FileName) {} + + const char* what () const throw() + { + return "Header Not Found"; + } + + std::string getFileName() const + { + return FName; + } + +private: + std::string FName; +}; +/**********************************************************************************************************************/ +/*@DEVI-struct for nullstmt*/ +struct NullStmtInfo +{ + NullStmtInfo (unsigned iColumn, unsigned iLine, std::string iFileName, bool iIsInMainFile, bool iIsInSysHeader) + { + Column = iColumn; + Line = iLine; + FileName = iFileName; + IsInMainFile = iIsInMainFile; + IsInSysHeader = iIsInSysHeader; + } + + unsigned Column; + unsigned Line; + std::string FileName; + bool IsInMainFile; + bool IsInSysHeader; +}; + +std::vector NullStmtProto; +/**********************************************************************************************************************/ +/*@DEVI-struct used for 8.8*/ +struct ExternObjInfo +{ + ExternObjInfo(unsigned int iLineNumber, unsigned int iColumnNumber, std::string iFileName\ + , std::string iXObjSLStr, std::string iXObjNameStr, FileID iXObjFID \ + , bool iHasMoreThanOneDefinition, bool iIsDefinition, bool iIsDeclaration) + { + LineNumber = iLineNumber; + ColumnNumber = iColumnNumber; + FileName = iFileName; + XObjSLStr = iXObjSLStr; + XObjNameStr = iXObjNameStr; + XObjFID = iXObjFID; + HasMoreThanOneDefinition = iHasMoreThanOneDefinition; + IsDefinition = iIsDefinition; + IsDeclaration = iIsDeclaration; + } + + unsigned int LineNumber; + unsigned int ColumnNumber; + std::string FileName; + std::string XObjSLStr; + std::string XObjNameStr; + FileID XObjFID; + bool HasMoreThanOneDefinition; + bool IsDefinition; + bool IsDeclaration; +}; + +std::vector ExternObjInfoProto; +/*@DEVI-end*/ +/**********************************************************************************************************************/ +/*@DEVI-struct used for rules 5.x*/ +struct IdentInfo +{ + IdentInfo(unsigned int iLine, unsigned int iColumn, std::string iFileName, std::string iName, \ + std::string iSLString, Devi::NodeKind iNK, bool iIsIncomplete, Devi::FunctionDeclKind IFDKind, \ + Devi::Scope iScope, std::string iScopeFuncitonName, bool iIsValid, bool iIsStatic) + { + Line = iLine; + Column = iColumn; + FileName = iFileName; + Name = iName; + SLString = iSLString; + NK = iNK; + IsIncomplete = iIsIncomplete; + FDKind = IFDKind; + Scope = iScope; + ScopeFunctionName = iScopeFuncitonName; + IsValid = iIsValid; + IsStatic = iIsStatic; + } + + unsigned int Line; + unsigned int Column; + std::string FileName; + std::string Name; + std::string SLString; + Devi::NodeKind NK; + bool IsIncomplete; + Devi::FunctionDeclKind FDKind; + Devi::Scope Scope; + std::string ScopeFunctionName; + bool IsValid; + bool IsStatic; +}; + +std::vector IdentInfoProto; + +std::unordered_map umRuleList; +/*@DEVI-end*/ +/**********************************************************************************************************************/ +/*mutator-lvl0 executable options*/ +enum MisraC +{ + NA=(0x1<<6), MisraC98=(0x1<<0), MisraC2004=(0x1<<2), MisraC2012=(0x1<<4), C1=(0x1<<1), C2=(0x1<<3), C3=(0x1<<5) +}; + +static llvm::cl::OptionCategory MutatorLVL0Cat("mutator-lvl0 options category"); +/*@DEVI-the option has been added since gcc does it.its as simple as that.*/ +cl::opt CheckSystemHeader("SysHeader", cl::desc("mutator-lvl0 will run through System Headers"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::ZeroOrMore); +cl::opt MainFileOnly("MainOnly", cl::desc("mutator-lvl0 will only report the results that reside in the main file"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::ZeroOrMore); +cl::opt MisraCVersion("MCV", cl::desc("choose the MisraC version to check against"), \ + cl::values(clEnumVal(MisraC98, "Misrac-1998"), clEnumVal(MisraC2004, "Misra-C:2004"), clEnumVal(MisraC2012, "Misra-C:2012"), \ + clEnumVal(C1, "Misra-C:1998"), clEnumVal(C2, "Misra-C:2004"), clEnumVal(C3, "Misra-C:2012")), cl::init(MisraC2004), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt MCE("MCE", cl::desc("MisraC switches to enable specific rule checks"), cl::init("10.1 "), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt MCD("MCD", cl::desc("MisraC switches to disable specific rule checks"), cl::init(" 9.3"), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt MCEA("MCEA", cl::desc("MisraC switch to enable all rule checks"), cl::init(true), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt MCDA("MCDA", cl::desc("MisraC switches to disable all rule checks"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt SFRCPP("SFRCPP", cl::desc("Enables SaferCPlusPlus rule checks"), cl::init(true), cl::cat(MutatorLVL0Cat), cl::Optional); +cl::opt mutagen("mutagen", cl::desc("runs mutagen after running the static tests"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::Optional); +/**********************************************************************************************************************/ +class StringOptionsParser +{ +friend class MutatorLVL0Tests; + +public: + StringOptionsParser() {} + + bool MC2Parser(void) + { + if (MCDA) + { + PopulateRuleList(false); + } + else if (MCEA) + { + PopulateRuleList(true); + } + + ParseString(); + + UpdateRuleList(); + + return true; + } + + void Dump(bool InArg) + { + if (InArg) + { + for (auto &iter : umRuleList) + { + std::cout<< "Debug-umRuleList: " << "RLKey: " << iter.first << " " << "RLValue: " << iter.second << "\n"; + } + + std::cout << "\n"; + + for (auto &iter : ParsedString) + { + std::cout << "Debug: " << "PSKey: " << iter.first << " " << "PSValue: " << iter.second << "\n"; + } + } + } + +private: + void PopulateRuleList(bool PopValue) + { + if (MisraCVersion < 0x4) + { + // C1 + umRuleList.insert({"0", PopValue}); + + typedef std::multimap::const_iterator Iter; + for (Iter iter = MC1EquivalencyMap.begin(), iterE = MC1EquivalencyMap.end(); iter != iterE; ++iter) + { + if (iter->first != std::prev(iter)->first) + { + umRuleList.insert({iter->first, PopValue}); + } + } + } + + if (MisraCVersion < 0x10) + { + // C2 + typedef std::map::const_iterator Iter; + for (Iter iter = MC2OptsMap.begin(), iterE = MC2OptsMap.end(); iter != iterE; ++iter) + { + umRuleList.insert({iter->first, PopValue}); + } + + } + + if (MisraCVersion < 0x40) + { + // C3 + } + } + + void ParseString(void) + { +#if 0 + std::cout << "MCD:" << MCD << "\n"; + std::cout << "MCE:" << MCE << "\n"; +#endif + + bool Disenable; + std::string TempString; + + if (MCDA) + { + Disenable = true; + TempString = MCE; + } + else if (MCEA) + { + Disenable = false; + TempString = MCD; + } + + size_t WhiteSpacePos = TempString.find(" ", 0U); + size_t OldPosition = 0U; + + if (WhiteSpacePos == std::string::npos) + { + ParsedString.push_back(std::make_pair(TempString, false)); + + return void(); + } + + while(WhiteSpacePos != std::string::npos) + { + OldPosition = WhiteSpacePos; + WhiteSpacePos = TempString.find(" ", WhiteSpacePos + 1U); + + if (WhiteSpacePos != std::string::npos) + { + ParsedString.push_back(std::make_pair(TempString.substr(OldPosition + 1U, WhiteSpacePos - OldPosition - 1U), Disenable)); + } + } + } + + void UpdateRuleList(void) + { + for (auto &iter : umRuleList) + { + for (auto &yaiter : ParsedString) + { + if (iter.first == yaiter.first) + { + iter.second = yaiter.second; + break; + } + } + } + } + + std::vector> ParsedString; + + std::vector> RuleList [[deprecated("now using umRuleList")]]; +}; +/**********************************************************************************************************************/ +/**************************************************ASTMatcher Callbacks************************************************/ +class [[deprecated("replaced by a more efficient class"), maybe_unused]] MCForCmpless : public MatchFinder::MatchCallback { +public: + MCForCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfor") != nullptr) + { + const ForStmt *FS = MR.Nodes.getNodeAs("mcfor"); + + SourceLocation SL = FS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + +#if 0 + std::cout << "14.8 : " << "\"For\" statement has no braces {}: " << "\n"; + std::cout << SL.printToString(*MR.SourceManager) << "\n" << "\n"; +#endif + } + else + { + std::cout << "matcher -mcfor- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class [[deprecated("replaced by a more efficient class"), maybe_unused]] MCWhileCmpless : public MatchFinder::MatchCallback { +public: + MCWhileCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcwhile") != nullptr) + { + const WhileStmt *WS = MR.Nodes.getNodeAs("mcwhile"); + + SourceLocation SL = WS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + +#if 0 + std::cout << "14.8 : " << "\"While\" statement has no braces {}: " << "\n"; + std::cout << SL.printToString(*MR.SourceManager) << "\n" << "\n"; +#endif + } + else + { + std::cout << "matcher -mcwhile- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCElseCmpless : public MatchFinder::MatchCallback { +public: + MCElseCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcelse") != nullptr) + { + const IfStmt *IS = MR.Nodes.getNodeAs("mcelse"); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); + } + + SourceLocation SL = IS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.9:" << "\"Else\" statement has no braces {}:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.9", "\"Else\" statement has no braces {}: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.9", "\"Else\" statement has no braces {}: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcelse- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCIfCmpless : public MatchFinder::MatchCallback { +public: + MCIfCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcif") != nullptr) + { + const IfStmt *IS = MR.Nodes.getNodeAs("mcif"); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); + } + + SourceLocation SL = IS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.9:" << "\"If\" statement has no braces {}:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.9", "\"If\" statement has no braces {}: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.9", "\"If\" statement has no braces {}: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcif- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class IfElseMissingFixer : public MatchFinder::MatchCallback +{ +public: + IfElseMissingFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcifelse") != nullptr) + { + const IfStmt *ElseIf = MR.Nodes.getNodeAs("mcifelse"); + + SourceLocation IFESL = ElseIf->getLocStart(); + CheckSLValidity(IFESL); + IFESL = Devi::SourceLocationHasMacro(IFESL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, IFESL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, IFESL)) + { + std::cout << "14.10:" << "\"If-Else If\" statement has no ending Else:"; + std::cout << IFESL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, IFESL, "14.10", "\"If-Else If\" statement has no ending Else: "); + JSONDocOUT.JSONAddElement(MR.Context, IFESL, "14.10", "\"If-Else If\" statement has no ending Else: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ElseIf), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcifelse- returned nullptr." << "\n"; + } + } + + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCSwitchBrkless : public MatchFinder::MatchCallback +{ +public: + MCSwitchBrkless (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcswitchbrk") != nullptr) + { + const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitchbrk"); + + SourceLocation SL = SS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "15.2:" << "\"SwitchStmt\" has a caseStmt that's missing a breakStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "15.2", "\"SwitchStmt\" has a caseStmt that's missing a breakStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "15.2", "\"SwitchStmt\" has a caseStmt that's missing a breakStmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcswitchbrk- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCSwitchDftLess : public MatchFinder::MatchCallback +{ +public: + MCSwitchDftLess (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcswitchdft") != nullptr) + { + const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitchdft"); + + SourceLocation SL = SS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "15.3:" << "\"SwitchStmt\" does not have a defaultStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "15.3", "\"SwitchStmt\" does not have a defaultStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "15.3", "\"SwitchStmt\" does not have a defaultStmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcswitchdft- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*misra-c 2004:15.1*/ +class MCSwitch151 : public MatchFinder::MatchCallback +{ +public: + MCSwitch151 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccmp151") != nullptr && MR.Nodes.getNodeAs("mccase151") != nullptr) + { + const CompoundStmt *CS = MR.Nodes.getNodeAs("mccmp151"); + const CaseStmt *SS = MR.Nodes.getNodeAs("mccase151"); + + SourceLocation SL = SS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + ASTContext *const ASTC = MR.Context; + + ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*CS); + + ast_type_traits::DynTypedNode ParentNode; + + /*@DEVI-assumptions:nothing has more than one parent in C.*/ + if (!NodeList.empty()) ParentNode = NodeList[0]; + else return void(); + + ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); + + std::string StringKind = ParentNodeKind.asStringRef().str(); + + if (StringKind != "SwitchStmt") + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "15.1:" << "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "15.1", "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "15.1", "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CS), *MR.Context); + } + } + } + } + else + { + std::cout << "matcher -mccmp151- or -mccase151- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCSwitch155 : public MatchFinder::MatchCallback +{ +public: + MCSwitch155 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcswitch155") != nullptr) + { + const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitch155"); + + SourceLocation SL = SS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "15.5:" << "\"SwitchStmt\" does not have a CaseStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "15.5", "\"SwitchStmt\" does not have a CaseStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "15.5", "\"SwitchStmt\" does not have a CaseStmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); + } + } + } + else + { + std::cout << "matcher -mcswitch155- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction161 : public MatchFinder::MatchCallback +{ +public: + MCFunction161 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunction161") != nullptr) + { + const FunctionDecl *FD = MR.Nodes.getNodeAs("mcfunction161"); + + if (FD->isVariadic()) + { + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "16.1:" << "\"FunctionDecl\" is variadic:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.1", "\"FunctionDecl\" is variadic: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.1", "\"FunctionDecl\" is variadic: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); + } + } + } + } + else + { + std::cout << "matcher -mcfunction161- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction162 : public MatchFinder::MatchCallback +{ +public: + MCFunction162 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mc162callexpr") != nullptr && MR.Nodes.getNodeAs("mc162funcdec") != nullptr) + { + const FunctionDecl *FD = MR.Nodes.getNodeAs("mc162funcdec"); + const CallExpr *CE = MR.Nodes.getNodeAs("mc162callexpr"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + return void(); + } + + + std::string FuncNameStr = FD->getNameInfo().getAsString(); + + if (CE->getDirectCallee()) + { + const FunctionDecl *FDCalled = CE->getDirectCallee(); + std::string CalledFuncNameStr = FDCalled->getNameInfo().getAsString(); + + if (FuncNameStr == CalledFuncNameStr) + { + std::cout << "16.2:" << "\"FunctionDecl\" is recursive:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.2", "\"FunctionDecl\" is recursive: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.2", "\"FunctionDecl\" is recursive: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CE), *MR.Context); + } + } + else + { + /*intentionally left blank.*/ + } + } + else + { + /*intentionally left blank.*/ + } + } + else + { + std::cout << "matcher -mc162funcdec- and/or -mc162callexpr- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction164 : public MatchFinder::MatchCallback +{ +public: + MCFunction164 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunc164") != nullptr) + { + const FunctionDecl *FD = MR.Nodes.getNodeAs("mcfunc164"); + const FunctionDecl *FDcl = FD->getDefinition(); + + /*to guard against function that have a declaration that is not a definition only.*/ + if (FDcl != nullptr) + { + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + return void(); + } + + SourceLocation SLDcl = FDcl->getLocStart(); + SLDcl = Devi::SourceLocationHasMacro(SLDcl, Rewrite, "start"); + + ArrayRef FDParmList = FD->parameters(); + + ArrayRef FDclParmList = FDcl->parameters(); + + if ( FD->getNumParams() != FDcl->getNumParams()) + { + std::cout << "numparam of functiondefinition and functionDecl dont match! : " << SL.printToString(*MR.SourceManager) << "\n" << "\n"; + } + else + { + if (FD->getNumParams() != 0) + { + for (unsigned x = 0; x < FD->getNumParams(); ++x) + { + if (FDParmList[x]->getNameAsString() != FDclParmList[x]->getNameAsString()) + { + std::cout << "16.4:" << "FunctionDecl parameter names are not the same as function definition parameter names:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.4", "FunctionDecl parameter names are not the same as function definition parameter names: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.4", "FunctionDecl parameter names are not the same as function definition parameter names: "); + + break; + } + else + { + /*intentionally left blank.*/ + } + } + } + } + } + } + else + { + std::cout << "matcher -mcfunc164- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction166 : public MatchFinder::MatchCallback +{ +public: + MCFunction166 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunc166") != nullptr) + { + const CallExpr *CE = MR.Nodes.getNodeAs("mcfunc166"); + + SourceLocation SL = CE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + const FunctionDecl *FD = CE->getDirectCallee(); + + DeclarationNameInfo DNI = FD->getNameInfo(); + + std::string FuncNameString = DNI.getAsString(); + + ASTContext *const ASTC = MR.Context; + + const SourceManager &SM = ASTC->getSourceManager(); + + /*start of 20.4*/ + if ((FuncNameString == "malloc" || FuncNameString == "calloc" || FuncNameString == "free" || FuncNameString == "realloc") && SM.isInSystemHeader(FD->getLocStart())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "20.4:" << "Dynamic heap memory allocation used:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "20.4", "Dynamic heap memory allocation used: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "20.4", "Dynamic heap memory allocation used: "); + + } + } + } + /*end of 20.4*/ + + /*start of 20.7*/ + if ((FuncNameString == "longjmp") && SM.isInSystemHeader(FD->getLocStart())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "20.7:" << "Use of lonjmp is illegal:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "20.7", "Use of longjmp is illegal: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "20.7", "Use of longjmp is illegal: "); + } + } + } + /*end of 20.7*/ + + /*start of 20.10*/ + if ((FuncNameString == "atof" || FuncNameString == "atoi" || FuncNameString == "atol") && SM.isInSystemHeader(FD->getLocStart())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "20.10:" << "Use of atof,atoi and atol is illegal:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "20.10", "Use of atof,atoi and atol is illegal: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "20.10", "Use of atof,atoi and atol is illegal: "); + } + } + } + /*end of 20.10*/ + + /*start of 20.11*/ + if ((FuncNameString == "abort" || FuncNameString == "exit" || FuncNameString == "getenv" || FuncNameString == "system") && SM.isInSystemHeader(FD->getLocStart())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "20.11:" << "Use of abort,exit,getenv and system is illegal:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "20.11", "Use of abort,exit,getenv and system is illegal : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "20.11", "Use of abort,exit,getenv and system is illegal : "); + } + } + } + /*end of 20.11*/ + + if (CE->getNumArgs() != FD->getNumParams()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "16.6:" << "CallExpr number of arguments does not equal the number of parameters in the declaration:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.6", "CallExpr number of arguments does not equal the number of parameters in the declaration: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.6", "CallExpr number of arguments does not equal the number of parameters in the declaration: "); + } + } + } + } + else + { + std::cout << "matcher -mcfunc166- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*the clang parser does not allow for such constructs.*/ +class [[maybe_unused]] MCFunction168 : public MatchFinder::MatchCallback +{ +public: + MCFunction168 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunc168") != nullptr) + { + const ReturnStmt *RT = MR.Nodes.getNodeAs("mcfunc168"); + + const Expr *RE [[maybe_unused]] = RT->getRetValue(); + + SourceLocation SL = RT->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + SourceLocation SLE = RT->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + + std::string RetType = Rewrite.getRewrittenText(SR); + +#if 0 + std::cout << RetType << "\n" << "\n"; +#endif + } + else + { + std::cout << "matcher -mcfunc168- returned nullptr." << "\n"; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction169 : public MatchFinder::MatchCallback +{ +public: + MCFunction169 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunc169") != nullptr) + { + const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("mcfunc169"); + + SourceLocation SL = ICE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + CastKind CK = ICE->getCastKind(); + + if (CK == CK_FunctionToPointerDecay) + { + std::cout << "16.9:" << "FunctionToPointerDecay:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.9", "FunctionToPointerDecay: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.9", "FunctionToPointerDecay: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-what is correct: match a pointer then run matcher for implicitcastexpressions of type arraytopointerdecay +that have unary(--,++) and binary(-,+) operators as parents*/ +class [[deprecated("replaced by something that actually works"), maybe_unused]] MCPA171 : public MatchFinder::MatchCallback +{ +public: + MCPA171 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcpa171") != nullptr) + { + const VarDecl *VD = MR.Nodes.getNodeAs("mcpa171"); + + QualType QT [[maybe_unused]] = VD->getType(); + +#if 0 + std::cout << QT.getAsString() << "\n" << "\n"; +#endif + } + } + +private: + Rewriter &Rewrite [[maybe_unused]]; +}; +/**********************************************************************************************************************/ +/*18.1 has false positives. incomplete types that have the same name as another incomplete +type in another scope are unrecognizable by this code.*/ +class MCSU184 : public MatchFinder::MatchCallback +{ +public: + MCSU184 (Rewriter &Rewrite) : Rewrite(Rewrite) + { + /*@DEVI-these push-backs generate garbage entries*/ + UnionInfoProto.push_back(UnionInfo()); + + StructInfoProto.push_back(StructInfo()); + + StructCounter = 0U; + UnionCounter = 0U; + } + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcsu184") != nullptr) + { + alreadymatched = false; + + const RecordDecl *RD = MR.Nodes.getNodeAs("mcsu184"); + + SourceLocation SL = RD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "18.4:" << "Union declared:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "18.4", "Union declared: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "18.4", "Union declared: "); + } + } + + std::string MatchedName = RD->getNameAsString(); + + for (unsigned x = 0; x < UnionCounter; ++x) + { + if (UnionInfoProto[x].UnionName == MatchedName) + { + alreadymatched = true; + + if (RD->isCompleteDefinition()) + { + UnionInfoProto[x].IsIncompleteType = false; + } + } + } + + if (alreadymatched == false) + { + UnionInfoProto.push_back(UnionInfo()); + UnionInfoProto[UnionCounter].UnionName = MatchedName; + UnionInfoProto[UnionCounter].UnionSL = SL.printToString(*MR.SourceManager); + UnionInfoProto[UnionCounter].FSL = FSL; + UnionInfoProto[UnionCounter].SL = SL; + + if (RD->isCompleteDefinition()) + { + /*this function has a declaration that is not a definition.*/ + UnionInfoProto[UnionCounter].IsIncompleteType = false; + } + + UnionCounter++; + } + } + + if (MR.Nodes.getNodeAs("mcsu181struct") != nullptr) + { + alreadymatched = false; + + const RecordDecl* RD = MR.Nodes.getNodeAs("mcsu181struct"); + + SourceLocation SL = RD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + std::string MatchedName = RD->getNameAsString(); + + for (unsigned x = 0; x < StructCounter; ++x) + { + if (StructInfoProto[x].StructName == MatchedName) + { + alreadymatched = true; + + if (RD->isCompleteDefinition()) + { + StructInfoProto[x].IsIncompleteType = false; + } + } + } + + if (alreadymatched == false) + { + StructInfoProto.push_back(StructInfo()); + StructInfoProto[StructCounter].StructName = MatchedName; + StructInfoProto[StructCounter].StructSL = SL.printToString(*MR.SourceManager); + StructInfoProto[StructCounter].FSL = FSL; + StructInfoProto[StructCounter].SL = SL; + + if (RD->isCompleteDefinition()) + { + StructInfoProto[StructCounter].IsIncompleteType = false; + } + + StructCounter++; + } + } + } + + virtual void onEndOfTranslationUnit() + { + for (unsigned x = 0; x < StructCounter; ++x) + { + if (StructInfoProto[x].IsIncompleteType) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, StructInfoProto[x].FSL.isInSystemHeader(), StructInfoProto[x].SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, StructInfoProto[x].FSL.getManager().isInMainFile(StructInfoProto[x].SL), StructInfoProto[x].SL)) + { + std::cout << "18.1:" << "Incomplete struct declared:"; + std::cout << StructInfoProto[x].StructSL << ":" << "\n"; + + XMLDocOut.XMLAddNode(StructInfoProto[x].FSL, StructInfoProto[x].SL, "18.1", "Incomplete struct declared: "); + JSONDocOUT.JSONAddElement(StructInfoProto[x].FSL, StructInfoProto[x].SL, "18.1", "Incomplete struct declared: "); + } + } + } + } + + for (unsigned x = 0; x < UnionCounter; ++x) + { + if (UnionInfoProto[x].IsIncompleteType) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, UnionInfoProto[x].FSL.isInSystemHeader(), UnionInfoProto[x].SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, UnionInfoProto[x].FSL.getManager().isInMainFile(UnionInfoProto[x].SL), UnionInfoProto[x].SL)) + { + std::cout << "18.1:" << "Incomplete union declared:"; + std::cout << UnionInfoProto[x].UnionSL << ":" << "\n"; + + XMLDocOut.XMLAddNode(UnionInfoProto[x].FSL, UnionInfoProto[x].SL, "18.1", "Incomplete union declared: "); + JSONDocOUT.JSONAddElement(UnionInfoProto[x].FSL, UnionInfoProto[x].SL, "18.1", "Incomplete union declared: "); + } + } + } + } + } + + +private: + struct UnionInfo + { + std::string UnionSL; + FullSourceLoc FSL; + SourceLocation SL; + std::string UnionName; + bool IsIncompleteType = true; + }; + + unsigned int UnionCounter; + + std::vector UnionInfoProto; + + struct StructInfo + { + std::string StructSL; + FullSourceLoc FSL; + SourceLocation SL; + std::string StructName; + bool IsIncompleteType = true; + }; + + unsigned StructCounter; + + bool alreadymatched = false; + + std::vector StructInfoProto; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCTypes6465 : public MatchFinder::MatchCallback +{ +public: + MCTypes6465 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mctype6465") != nullptr) + { + const FieldDecl *FD = MR.Nodes.getNodeAs("mctype6465"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QualType QT = FD->getType(); + const clang::Type* TP = QT.getTypePtr(); + + if ( !(TP->hasUnsignedIntegerRepresentation() || TP->hasSignedIntegerRepresentation())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*@DEVI-this part is ueless since the clang parser wont let such a bitfield through.*/ + std::cout << "6.4:" << "BitField has a type other than int or unsigned int:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.4", "BitField has a type other than int or unsigned int: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.4", "BitField has a type other than int or unsigned int: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); + } + } + } + } + + ASTContext *const ASTC = MR.Context; + unsigned int BitWidth = FD->getBitWidthValue(*ASTC); + + if (TP->hasSignedIntegerRepresentation()) + { + if (BitWidth < 2U) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "6.5:" << "BitField of type signed integer has a length of less than 2 in bits:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.5", "BitField of type signed integer has a length of less than 2 in bits : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.5", "BitField of type signed integer has a length of less than 2 in bits : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); + } + } + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCDCDF81 : public MatchFinder::MatchCallback +{ +public: + MCDCDF81 (Rewriter &Rewrite) : Rewrite(Rewrite) + { + /*@DEVI-the pushback generates garbage entries.*/ + FuncInfoProto.push_back(FuncInfo()); + + VecC = 0U; + }; + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcdcdf81") != nullptr) + { + alreadymatched = false; + + const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf81"); + DeclarationNameInfo DNI = FD->getNameInfo(); + std::string MatchedName = DNI.getAsString(); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + SourceLocation SLE = FD->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + const SourceManager &SM = ASTC->getSourceManager(); + FullSourceLoc FSL = ASTC->getFullLoc(SL); + FullSourceLoc FSLE = ASTC->getFullLoc(SLE); + + /*start of 8.5*/ + bool FunctionDeclaredInsideHeader = false; + + if (FD->isThisDeclarationADefinition()) + { + for (unsigned x = 0; x < IncludeFileArr.size(); ++x) + { + if (SM.getFilename(SL).str() == IncludeFileArr[x]) + { + FunctionDeclaredInsideHeader = true; + } + } + } + + if (FunctionDeclaredInsideHeader) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "8.5:" << "Function definition inside a header file:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "8.5", "Function definition inside a header file : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "8.5", "Function definition inside a header file : "); + } + } + } + /*end of 8.5*/ + + + /*start of checks for 19.5*/ + /*has false positives. false positives go away if the main.c is not included(main.c includes another header)*/ + if (FD->isThisDeclarationADefinition()) + { + for (unsigned x = 0; x < MacroDefSourceLocation.size(); ++x) + { + if (FSL.isBeforeInTranslationUnitThan(MacroDefSourceLocation[x]) && \ + !FSLE.isBeforeInTranslationUnitThan(MacroDefSourceLocation[x]) && \ + SM.isInMainFile(MacroDefSourceLocation[x]) && !SM.isInSystemHeader(MacroDefSourceLocation[x])) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "19.5:" << "Macro defined inside a block:"; +#if 0 + std::cout << MacroDefSourceLocation[x].printToString(*MR.SourceManager) << " " << MacroNameString[x] << "\n" << "\n"; +#endif + std::cout << MacroDefSourceLocation[x].printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, MacroDefSourceLocation[x], "19.5", "Macro defined inside a block : "); + JSONDocOUT.JSONAddElement(MR.Context, MacroDefSourceLocation[x], "19.5", "Macro defined inside a block : "); + } + } + } + } + + for (unsigned x = 0; x < MacroUndefSourceLocation.size(); ++x) + { + if (FSL.isBeforeInTranslationUnitThan(MacroUndefSourceLocation[x]) && \ + !FSLE.isBeforeInTranslationUnitThan(MacroUndefSourceLocation[x]) && \ + SM.isInMainFile(MacroUndefSourceLocation[x]) && !SM.isInSystemHeader(MacroUndefSourceLocation[x])) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "19.5:" << "Macro undefined inside a block:"; + std::cout << MacroUndefSourceLocation[x].printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, MacroUndefSourceLocation[x], "19.5", "Macro undefined inside a block : "); + JSONDocOUT.JSONAddElement(MR.Context, MacroUndefSourceLocation[x], "19.5", "Macro undefined inside a block : "); + } + } + } + } + } + /*end of checks for 19.5*/ + + /*going through the already matched functions,making sure we are not adding duplicates.*/ + for (unsigned x = 0; x < VecC; ++x) + { + if (FuncInfoProto[x].FuncNameString == MatchedName) + { + alreadymatched = true; + + if (!FD->isThisDeclarationADefinition()) + { + FuncInfoProto[x].HasDecThatisNotDef = true; + } + } + } + + if (alreadymatched == false) + { + FuncInfoProto.push_back(FuncInfo()); + FuncInfoProto[VecC].FuncNameString = MatchedName; + + if (!FD->isThisDeclarationADefinition()) + { + /*this function has a declaration that is not a definition.*/ + FuncInfoProto[VecC].HasDecThatisNotDef = true; + } + else + { + /*save the sourcelocation only if the functiondecl is a definition.*/ + FuncInfoProto[VecC].StrcSL = SL.printToString(*MR.SourceManager); + FuncInfoProto[VecC].FuncSL = SL; + FuncInfoProto[VecC].FuncFSL = MR.Context->getFullLoc(SL); + } + + VecC++; + } + } + } + + virtual void onEndOfTranslationUnit() + { + + for (unsigned x = 0; x < VecC; ++x) + { + if (FuncInfoProto[x].HasDecThatisNotDef == false) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, FuncInfoProto[x].FuncFSL.isInSystemHeader(), FuncInfoProto[x].FuncSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, FuncInfoProto[x].FuncFSL.getManager().isInMainFile(FuncInfoProto[x].FuncSL), FuncInfoProto[x].FuncSL)) + { + std::cout << "8.1:" << "Function does not have a FunctionDecl that is not a definition:"; + std::cout << FuncInfoProto[x].StrcSL << ":" << "\n"; + + XMLDocOut.XMLAddNode(FuncInfoProto[x].FuncFSL, FuncInfoProto[x].FuncSL, "8.1", "Function does not have a FunctionDecl that is not a definition : "); + JSONDocOUT.JSONAddElement(FuncInfoProto[x].FuncFSL, FuncInfoProto[x].FuncSL, "8.1", "Function does not have a FunctionDecl that is not a definition : "); + } + } + } + } + + } + +private: + struct FuncInfo { + std::string FuncNameString; + std::string StrcSL; + bool HasDecThatisNotDef = false; + SourceLocation FuncSL; + FullSourceLoc FuncFSL; + }; + + std::vector FuncInfoProto; + + unsigned int VecC; + + bool alreadymatched = false; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*Notes:clang does not let 8.2 and 8.3 through.*/ +/*clang gives the implicitly-typed vardecl and functiondecl a default type in the AST so we cant use that. +we should just get the rewritten text and do string searches inside. thats the only way i can think of.*/ +class [[maybe_unused]] MCDCDF82 : public MatchFinder::MatchCallback +{ +public: + MCDCDF82 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcdcdf82") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf82"); + + std::string QualifiedName = VD->getQualifiedNameAsString(); + + QualType QT [[maybe_unused]] = VD->getType(); + +#if 0 + std::cout << QualifiedName << "\n" << "\n"; +#endif + } + } + +private: + Rewriter &Rewrite [[maybe_unused]]; +}; +/**********************************************************************************************************************/ +/*this class also matches aggregate types. a simple aggregate check should fix that, if need be.*/ +class MCInit91 : public MatchFinder::MatchCallback +{ +public: + MCInit91 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcinit91") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("mcinit91"); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SourceLocation SLMID; + + if (SL.isMacroID()) + { + SLMID = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + SourceLocation SLE = VD->getLocEnd(); + SourceLocation SLEMID; + + if (SLE.isMacroID()) + { + SLEMID = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + } + + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + QualType QT = VD->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + ASTContext *const ASTC = MR.Context; + + SourceManager &SM = ASTC->getSourceManager(); + + /*start of 8.5*/ + bool VarDeclaredInsideHeader = false; + + if (VD->isThisDeclarationADefinition(*ASTC) && !(!VD->isLocalVarDecl() && VD->isLocalVarDeclOrParm())) + { +#if 0 + std::cout << "XXXXXXXXXXXXXXXXXXXXXXXX" << " " << IncludeFileArr.size() << "\n"; +#endif + for (unsigned x = 0; x < IncludeFileArr.size(); ++x) + { + if (SM.getFilename(SL).str() == IncludeFileArr[x]) + { + VarDeclaredInsideHeader = true; + } + } + } + + if (VarDeclaredInsideHeader) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "8.5:" << "Variable definition inside a header file:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "8.5", "Variable definition inside a header file : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "8.5", "Variable definition inside a header file : "); + } + } + } + /*end of 8.5*/ + + /*start of 8.12*/ + if (!VD->hasInit()) + { + if (VD->hasExternalStorage()) + { + if (TP->isIncompleteArrayType()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*end of 8.12*/ + std::cout << "8.12:" << "External array type is incomplete and has no initialization:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "8.12", "External array type is incomplete and has no initialization : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "8.12", "External array type is incomplete and has no initialization : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*VD), *MR.Context); + } + } + } + } + } + } + /*start of 9.2*/ + else + { + if (TP->isArrayType() || TP->isStructureType()) + { + /*JANKY*/ + const Expr* InitExpr [[maybe_unused]] = VD->getInit(); + SourceRange InitExprSR; + SourceLocation IESL = InitExpr->getLocStart(); + CheckSLValidity(IESL); + IESL = Devi::SourceLocationHasMacro(IESL, Rewrite, "start"); + + CheckSLValidity(IESL); + + SourceLocation IESLE = InitExpr->getLocEnd(); + IESLE = Devi::SourceLocationHasMacro(IESLE, Rewrite, "end"); + InitExprSR.setBegin(IESL); + InitExprSR.setEnd(IESLE); + + std::string InitExprString = Rewrite.getRewrittenText(InitExprSR); + size_t openingcbraces = InitExprString.find("{", 0); + size_t closingcbraces = InitExprString.find("}", 0); + + if (openingcbraces == std::string::npos || closingcbraces == std::string::npos) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { +#if 0 + std::cout << "9.2:" << "Curly braces not used:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "9.2", "Curly braces not used : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "9.2", "Curly braces not used : "); +#endif + } + } + } + } + } + /*end of 9.2*/ + + /*we only check for local static since global static is meaningless.*/ + if (!VD->isStaticLocal() && VD->isLocalVarDecl()) + { + if (!VD->hasInit()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "9.1:" << "staic local variable does not have initialization:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "9.1", "staic local variable does not have initialization : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "9.1", "staic local variable does not have initialization : "); + } + } + } + } + } + + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class [[maybe_unused]] MCInit92 : public MatchFinder::MatchCallback +{ +public: + MCInit92 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcinit92") != nullptr) + { + const InitListExpr* ILE = MR.Nodes.getNodeAs("mcinit92"); + const VarDecl* VD = MR.Nodes.getNodeAs("mcinit92daddy"); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + unsigned int NumInits [[maybe_unused]] = ILE->getNumInits(); + +#if 0 + std::cout << NumInits << "\n" << "\n"; +#endif + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCInit93 : public MatchFinder::MatchCallback +{ +public: + MCInit93 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcinit93") != nullptr && MR.Nodes.getNodeAs("mcinit93daddy") != nullptr) + { + const EnumConstantDecl * ECD [[maybe_unused]] = MR.Nodes.getNodeAs("mcinit93"); + const EnumDecl* ED = MR.Nodes.getNodeAs("mcinit93daddy"); + /*do note that this pointer might very well be nullptr. we are actually counting on that. + it tells us we could not match an integer initialization for this enumconstantdecl.*/ + const IntegerLiteral* IL = MR.Nodes.getNodeAs("mcinit93kiddy"); + + SourceLocation SL = ED->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + newSourceLocation = SL; + + if (oldSourceLocation != newSourceLocation) + { + someoneHasInit = false; + everyoneHasInit = true; + isFirstElement = true; + if (IL == nullptr) + { + doesFirstElementHaveInit = false; + everyoneHasInit = false; + } + else + { + doesFirstElementHaveInit = true; + } + } + else + { + isFirstElement = false; + } + + if (oldSourceLocation == newSourceLocation) + { + if (IL == nullptr) + { + everyoneHasInit = false; + } + else + { + someoneHasInit = true; + } + + if (doesFirstElementHaveInit) + { + if (!everyoneHasInit && someoneHasInit) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*in breach of misrac*/ + std::cout << "9.3:" << "first enumeration has integerliteral initialization but not all enumerations do:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "9.3", "first enumeration has integerliteral initialization but not all enumerations do : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "9.3", "first enumeration has integerliteral initialization but not all enumerations do : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ECD), *MR.Context); + } + } + } + } + else + { + /*doesnt mean anything*/ + } + } + else + { + if (IL != nullptr) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + /*in breach of misrac*/ + std::cout << "9.3:" << "first enumeration does not have integerliteral initialization but at least one other enumeration does:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "9.3", "first enumeration does not have integerliteral initialization but at least one other enumeration does : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "9.3", "first enumeration does not have integerliteral initialization but at least one other enumeration does : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ECD), *MR.Context); + } + } + } + } + else + { + /*doesnt mean anything*/ + } + } + } + + oldSourceLocation = newSourceLocation; + } + } + +private: + /*doing this instead of saving everything and then running onendoftranslationunit is faster and less memory-expensive. + needless to say, for this to work, we are counting on clang's matching pattern.*/ + SourceLocation oldSourceLocation; + SourceLocation newSourceLocation; + + bool isFirstElement = false; + bool doesFirstElementHaveInit = false; + bool someoneHasInit = false; + bool everyoneHasInit = true; + + Rewriter &Rewrite; +}; + +/**********************************************************************************************************************/ +class MCExpr123 : public MatchFinder::MatchCallback +{ +public: + MCExpr123 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr123kiddy") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr123kiddy"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + ASTContext *const ASTC = MR.Context; + + if (EXP->HasSideEffects(*ASTC, true)) + { + std::cout << "12.3:" << "sizeof working on an expr with a side-effect:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.3", "sizeof working on an expr with a side-effect : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.3", "sizeof working on an expr with a side-effect : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr124 : public MatchFinder::MatchCallback +{ +public: + MCExpr124 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr124") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr124"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + ASTContext *const ASTC = MR.Context; + + if (EXP->HasSideEffects(*ASTC, true)) + { + std::cout << "12.4:" << "Righ-hand expr has side-effect:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.4", "Righ-hand expr has side-effect"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.4", "Righ-hand expr has side-effect"); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*DEVI-if all operands are boolean, this class will still tag em as inconsistent(with misrac).*/ +class MCExpr125 : public MatchFinder::MatchCallback +{ +public: + MCExpr125 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("lrhs") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("lrhs"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext *const ASTC [[maybe_unused]] = MR.Context; + + QualType QT [[maybe_unused]] = EXP->getType(); + + SourceLocation SLE = EXP->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + + std::string StrText = Rewrite.getRewrittenText(SR); + if (StrText[0] == '(' && StrText[StrText.length() - 1U] == ')') + { + hasParantheses = true; + } + else + { + hasParantheses = false; + } + + if (hasParantheses || SL.isMacroID()) + { + /*intentionally left blank.*/ + } + else + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "12.5:" << "RHS and/or LHS operands are not primary expressions:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.5", "RHS and/or LHS operands are not primary expressions : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.5", "RHS and/or LHS operands are not primary expressions : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + } + } + +private: + bool hasParantheses = false; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr126 : public MatchFinder::MatchCallback +{ +public: + MCExpr126 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr126rl") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr126rl"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + if (!EXP->isKnownToHaveBooleanValue()) + { + std::cout << "12.6:" << "RHS and/or LHS operands are not effectively-boolean values:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.6", "RHS and/or LHS operands are not effectively-boolean values : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.6", "RHS and/or LHS operands are not effectively-boolean values : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr127 : public MatchFinder::MatchCallback +{ +public: + MCExpr127 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr127rl") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr127rl"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType QT = EXP->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + if (TP->hasSignedIntegerRepresentation() && TP->isIntegerType()) + { + std::cout << "12.7:" << "Bitwise operator has signed RHS and/or LHS operands:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.7", "Bitwise operator has signed RHS and/or LHS operands: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.7", "Bitwise operator has signed RHS and/or LHS operands: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class [[maybe_unused]] MCExpr128 : public MatchFinder::MatchCallback +{ +public: + MCExpr128 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr128lhs") != nullptr && MR.Nodes.getNodeAs("mcexpr128rhs") != nullptr) + { + const Expr* RHS = MR.Nodes.getNodeAs("mcexpr128rhs"); + const Expr* LHS = MR.Nodes.getNodeAs("mcexpr128lhs"); + + SourceLocation SL = RHS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType RQT = RHS->getType(); + QualType LQT = LHS->getType(); + + ASTContext *const ASTC = MR.Context; + + const clang::Type* RTP [[maybe_unused]] = RQT.getTypePtr(); + const clang::Type* LTP = LQT.getTypePtr(); + + const clang::Type* CanonType = ASTC->getCanonicalType(LTP); + + uint64_t LHSSize = ASTC->getTypeSize(CanonType); + + llvm::APSInt Result; + + if (RHS->isIntegerConstantExpr(Result, *ASTC, nullptr, true)) + { + if ((Result >= (LHSSize - 1U)) || (Result <= 0)) + { + std::cout << "12.8:" << "shift size should be between zero and one less than the size of the LHS operand:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.8", "shift size should be between zero and one less than the size of the LHS operand: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.8", "shift size should be between zero and one less than the size of the LHS operand: "); + + /*@DEVI-FIXME-cant extract this one correctly*/ + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*RHS), *MR.Context); + } + } + } + + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr129 : public MatchFinder::MatchCallback +{ +public: + MCExpr129 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr129") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr129"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType QT = EXP->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + if (TP->isIntegerType() && TP->hasUnsignedIntegerRepresentation()) + { + std::cout << "12.9:" << "UnaryOperator - has an expr with an unsigned underlying type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.9", "UnaryOperator - has an expr with an unsigned underlying type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.9", "UnaryOperator - has an expr with an unsigned underlying type: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr1210 : public MatchFinder::MatchCallback +{ +public: + MCExpr1210 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr1210") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr1210"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "12.10:" << "Comma used:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.10", "Comma used: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.10", "Comma used: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr1213 : public MatchFinder::MatchCallback +{ +public: + MCExpr1213 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr1213") != nullptr) + { + const UnaryOperator* UO = MR.Nodes.getNodeAs("mcexpr1213"); + + SourceLocation SL = UO->getOperatorLoc(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "12.13:" << "Unary ++ or -- have been used in an expr with other operators:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.13", "Unary ++ or -- have been used in an expr with other operators: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.13", "Unary ++ or -- have been used in an expr with other operators: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*UO), *MR.Context); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE131 : public MatchFinder::MatchCallback +{ +public: + MCCSE131 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("cse131rlhs") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("cse131rlhs"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + if (EXP->isKnownToHaveBooleanValue()) + { + std::cout << "13.1:" << "assignment operator used in an expr that is known to return boolean:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.1", "assignment operator used in an expr that is known to return boolean: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.1", "assignment operator used in an expr that is known to return boolean: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE132 : public MatchFinder::MatchCallback +{ +public: + MCCSE132 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse132") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mccse132"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + if (!EXP->isKnownToHaveBooleanValue()) + { + std::cout << "13.2:" << "Implicit test of an expr against zero which is not known to return a boolean result:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.2", "Implicit test of an expr against zero which is not known to return a boolean result: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.2", "Implicit test of an expr against zero which is not known to return a boolean result: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE1332 : public MatchFinder::MatchCallback +{ +public: + MCCSE1332 (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse1332rl") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mccse1332rl"); + const BinaryOperator* BO = MR.Nodes.getNodeAs("mccse1332daddy"); + + SourceLocation SLD = BO->getLocStart(); + CheckSLValidity(SLD); + SLD = Devi::SourceLocationHasMacro(SLD, Rewrite, "start"); + NewSL = SLD; + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QualType QT = EXP->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + if (OldSL != NewSL) + { + if (TP->hasFloatingRepresentation()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "13.3:" << "Float type expression checked for equality/inequality:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.3", "Float type expression checked for equality/inequality: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.3", "Float type expression checked for equality/inequality: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + } + + OldSL = NewSL; + } + } + +private: + SourceLocation NewSL; + SourceLocation OldSL; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE134 : public MatchFinder::MatchCallback +{ +public: + MCCSE134 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse134") != nullptr) + { + AlreadyHaveAHit = false; + + const ForStmt* FS = MR.Nodes.getNodeAs("mccse134"); + + SourceLocation SL = FS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + const Expr* FSCond = FS->getCond(); + const Expr* FSInc = FS->getInc(); + +#if 0 + if (FSCond != nullptr) + { + std::string multix = Rewrite.getRewrittenText(FSCond->getSourceRange()); + std::cout << "diagnostic" << ":" << multix << "\n"; + } +#endif + + if (FSCond != nullptr) + { + QualType QTCond = FSCond->getType(); + + const clang::Type* TPCond = QTCond.getTypePtr(); + + if (TPCond->hasFloatingRepresentation()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "13.4:" << "Float type used in the controlling expression of a forstmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + AlreadyHaveAHit = true; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FS), *MR.Context); + } + } + } + } + } + + if (FSInc != nullptr && !AlreadyHaveAHit) + { + QualType QTInc = FSInc->getType(); + + const clang::Type* TPInc = QTInc.getTypePtr(); + + if (TPInc->hasFloatingRepresentation()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "13.4:" << "Float type used in the controlling expression of a forstmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + AlreadyHaveAHit = true; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FS), *MR.Context); + } + } + } + } + } + } + } + +private: + bool AlreadyHaveAHit = false; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*JANKY*/ +/*if a for controlling var is modified in the body using a pointer, then this class wont find it.*/ +/*the class will only work properly only if there is one controlling loop variable. +the behavior is undefined for more than one variable.*/ +class MCCSE136 : public MatchFinder::MatchCallback +{ +public: + MCCSE136 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse136kiddo") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mccse136kiddo"); + const ForStmt* FS = MR.Nodes.getNodeAs("mccse136daddy"); + + const Stmt* FSInit = FS->getInit(); + const Expr* FSInc = FS->getInc(); + const Expr* FSCond [[maybe_unused]] = FS->getCond(); + + /*underdev*/ + if (FSCond != nullptr) + { + SourceLocation CSL = FSCond->getLocStart(); + CheckSLValidity(CSL); + SourceLocation CSLE = FSCond->getLocEnd(); + SourceRange CSR; + CSR.setBegin(CSL); + CSR.setEnd(CSLE); + + std::string outstring = Rewrite.getRewrittenText(CSR); + +#if 0 + std::cout << "XXXXXXXXXXXXXXXXXXXXXX" << outstring << "\n"; +#endif + } + + + SourceLocation SLD = FS->getLocStart(); + CheckSLValidity(SLD); + SLD = Devi::SourceLocationHasMacro(SLD, Rewrite, "start"); + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (FSInit != nullptr && FSInc != nullptr) + { + SourceLocation SLFSInit = FSInit->getLocStart(); + SLFSInit = Devi::SourceLocationHasMacro(SLFSInit, Rewrite, "start"); + SourceLocation SLFSInc = FSInc->getLocStart(); + SLFSInc = Devi::SourceLocationHasMacro(SLFSInc, Rewrite, "start"); + + DeclarationNameInfo DNI = DRE->getNameInfo(); + + std::string NameString = DNI.getAsString(); + + /*JANKY*/ + /*@DEVI-the third condition is put in place to accomodate the prefix unary increment or decrement operator.*/ + if (SLFSInit == SL || SLFSInc == SL || SLFSInc.getLocWithOffset(2) == SL) + { + ControlVarName = NameString; + } + else + { + if (ControlVarName == NameString) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "13.6:" << "ForStmt controlling variable modified in the body of the loop:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.6", "ForStmt controlling variable modified in the body of the loop: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.6", "ForStmt controlling variable modified in the body of the loop: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); + } + } + } + } + } + + } + } + } + +private: + std::string ControlVarName; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF144 : public MatchFinder::MatchCallback +{ +public: + MCCF144 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccf144") != nullptr) + { + const GotoStmt* GS = MR.Nodes.getNodeAs("mccf144"); + + SourceLocation SL = GS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "14.4:" << "GotoStmt used:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.4", "GotoStmt used: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.4", "GotoStmt used: "); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF145 : public MatchFinder::MatchCallback +{ +public: + MCCF145 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccf145") != nullptr) + { + const ContinueStmt* CS = MR.Nodes.getNodeAs("mccf145"); + + SourceLocation SL = CS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "14.5:" << "ContinueStmt used:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.5", "ContinueStmt used: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.5", "ContinueStmt used: "); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF146 : public MatchFinder::MatchCallback +{ +public: + MCCF146 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccffofo") != nullptr) + { + const ForStmt* FS = MR.Nodes.getNodeAs("mccffofo"); + + SL = FS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + if (MR.Nodes.getNodeAs("mccfwuwu") != nullptr) + { + const WhileStmt* WS = MR.Nodes.getNodeAs("mccfwuwu"); + + SL = WS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + if (MR.Nodes.getNodeAs("mccfdodo") != nullptr) + { + const DoStmt* DS = MR.Nodes.getNodeAs("mccfdodo"); + + SL = DS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + NewSL = SL; + + if (OldSL != NewSL) + { + AlreadyTagged = false; + BreakCounter = 1U; + } + + if (OldSL == NewSL) + { + BreakCounter++; + } + + if (BreakCounter >= 2U && !AlreadyTagged) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.6:" << "More than one BreakStmt used in the loop counter:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + AlreadyTagged = true; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.6", "More than one BreakStmt used in the loop counter: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.6", "More than one BreakStmt used in the loop counter: "); + } + } + } + + OldSL = NewSL; + } + +private: + SourceLocation OldSL; + SourceLocation NewSL; + bool AlreadyTagged = false; + unsigned int BreakCounter = 0U; + SourceLocation SL; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF147 : public MatchFinder::MatchCallback +{ +public: + MCCF147 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccf147") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("mccf147"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + NewSL = SL; + + if (OldSL != NewSL) + { + AlreadyTagged = false; + ReturnCounter = 1U; + } + + if (OldSL == NewSL) + { + ReturnCounter++; + } + + if (ReturnCounter >= 2U && !AlreadyTagged) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.7:" << "More than one ReturnStmt used in the body of FunctionDecl:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + AlreadyTagged = true; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.7", "More than one ReturnStmt used in the body of FunctionDecl: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.7", "More than one ReturnStmt used in the body of FunctionDecl: "); + } + } + } + + OldSL = NewSL; + } + } + +private: + SourceLocation NewSL; + SourceLocation OldSL; + unsigned int ReturnCounter = 0U; + bool AlreadyTagged = false; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF148 : public MatchFinder::MatchCallback +{ +public: + MCCF148 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + + if (MR.Nodes.getNodeAs("mccf148for") != nullptr) + { + const ForStmt* FS = MR.Nodes.getNodeAs("mccf148for"); + + SL = FS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.8:" << "ForStmt does not have a child CompoundStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "ForStmt does not have a child CompoundStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "ForStmt does not have a child CompoundStmt: "); + } + } + } + + if (MR.Nodes.getNodeAs("mccf148while") != nullptr) + { + const WhileStmt* WS = MR.Nodes.getNodeAs("mccf148while"); + + SL = WS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.8:" << "WhileStmt does not have a child CompoundStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "WhileStmt does not have a child CompoundStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "WhileStmt does not have a child CompoundStmt: "); + } + } + } + + if (MR.Nodes.getNodeAs("mccf148do") != nullptr) + { + const DoStmt* DS = MR.Nodes.getNodeAs("mccf148do"); + + SL = DS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.8:" << "DoStmt does not have a child CompoundStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "DoStmt does not have a child CompoundStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "DoStmt does not have a child CompoundStmt: "); + } + } + } + + if (MR.Nodes.getNodeAs("mccf148switch") != nullptr) + { + const SwitchStmt* SS = MR.Nodes.getNodeAs("mccf148switch"); + + SL = SS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "14.8:" << "SwitchStmt does not have a child CompoundStmt:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "SwitchStmt does not have a child CompoundStmt: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "SwitchStmt does not have a child CompoundStmt: "); + } + } + } + } + +private: + SourceLocation SL; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCSwitch154 : public MatchFinder::MatchCallback\ +{ +public: + MCSwitch154 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcswitch154"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + if (EXP->isKnownToHaveBooleanValue()) + { + std::cout << "15.4:" << "Switch expression is effectively boolean:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "15.4", "Switch expression is effectively boolean: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "15.4", "Switch expression is effectively boolean: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-the current implementation of 11.3 is very strict.*/ +class MCPTC111 : public MatchFinder::MatchCallback +{ +public: + MCPTC111 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcptc111") != nullptr) + { + const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("mcptc111"); + + SourceLocation SL = ICE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QualType QT = ICE->getType(); + + const clang::Type* TP = QT.getTypePtr(); + +#if 0 + ASTContext *const ASTC = MR.Context; + + const ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*ICE); + + /*assumptions:implicitcastexpr does not have more than one parent in C.*/ + const ast_type_traits::DynTypedNode ParentNode = NodeList[0]; + + ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); + + std::string StringKind = ParentNodeKind.asStringRef().str(); + + const ImplicitCastExpr* ParentICE = ParentNode.get(); +#endif + + CastKind CK = ICE->getCastKind(); + + bool ShouldBeTagged111 = false; + + if (TP->isFunctionPointerType()) + { + if (((CK != CK_IntegralToPointer) && (CK != CK_PointerToIntegral) && \ + (CK != CK_LValueToRValue) && (CK != CK_FunctionToPointerDecay) && \ + (CK != CK_ArrayToPointerDecay))) + { + ShouldBeTagged111 = true; + } + + if (CK == CK_BitCast) + { + ShouldBeTagged111 = true; + } + + if (ShouldBeTagged111) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.1:" << "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.1", "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.1", "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); + } + } + } + } + } + + if (CK == CK_IntegralToFloating || CK == CK_FloatingToIntegral) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.1/2:" << "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); + } + } + } + } + + if ((CK == CK_IntegralToPointer) || (CK == CK_PointerToIntegral)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.3:" << "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.3", "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.3", "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); + } + } + } + } + + if (CK == CK_BitCast || CK == CK_PointerToBoolean || CK == CK_AnyPointerToBlockPointerCast) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.x:" << "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.x", "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.x", "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); + } + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE137 : public MatchFinder::MatchCallback +{ +public: + MCCSE137 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse137") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mccse137"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext *const ASTC = MR.Context; + + if (EXP->isKnownToHaveBooleanValue()) + { + if (EXP->isEvaluatable(*ASTC, Expr::SE_NoSideEffects)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "13.7:" << "EffectivelyBooleanExpr's result is known at compile-time:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.7", "EffectivelyBooleanExpr's result is known at compile-time: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.7", "EffectivelyBooleanExpr's result is known at compile-time: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + } + + QualType QT = EXP->getType(); + const clang::Type* TP = QT.getTypePtr(); + + if (TP->isIntegerType()) + { + ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*EXP); + + ast_type_traits::DynTypedNode ParentNode; + /*assumptions:nothing has more than one parent in C.*/ + if (!NodeList.empty()) ParentNode = NodeList[0]; + else return void(); + + ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); + + std::string StringKind = ParentNodeKind.asStringRef().str(); + + if (StringKind == "ImplicitCastExpr") + { + + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*if the call is coming from another file, getdirectcalle returns the definition, +but if its coming from the same file, it returns the declaration that is not a definition.*/ +/*if youve already matched the definition, getdefinition returns null.*/ +class MCDCDF810 : public MatchFinder::MatchCallback +{ +public: + MCDCDF810 (Rewriter &Rewrite) : Rewrite(Rewrite) + { + /*@DEVI-the pushback here generates garbage entries.*/ + FuncScopeProto.push_back(FuncScope()); + + VecC = 0U; + } + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcdcdf810") != nullptr && MR.Nodes.getNodeAs("mcdcdf810daddy") != nullptr) + { + AlreadyTagged = false; + + const CallExpr* CE = MR.Nodes.getNodeAs("mcdcdf810"); + const FunctionDecl* FDDad = MR.Nodes.getNodeAs("mcdcdf810daddy"); + const FunctionDecl* FD = CE->getDirectCallee(); + const FunctionDecl* FDDef = FD->getDefinition();; + + if (FDDef == nullptr) + { + FDDef = CE->getDirectCallee(); + } + + SourceLocation CESL = CE->getLocStart(); + CheckSLValidity(CESL); + CESL = Devi::SourceLocationHasMacro(CESL, Rewrite, "start"); + + SourceLocation FDDadSL = FDDad->getLocStart(); + CheckSLValidity(FDDadSL); + FDDadSL = Devi::SourceLocationHasMacro(FDDadSL, Rewrite, "start"); + + SourceLocation FDSL = FDDef->getLocStart(); + CheckSLValidity(FDSL); + FDSL = Devi::SourceLocationHasMacro(FDSL, Rewrite, "start"); + + ASTContext *const ASTC = MR.Context; + + FullSourceLoc FDDadFullSL = ASTC->getFullLoc(FDDadSL); + FullSourceLoc FDFullSL = ASTC->getFullLoc(FDSL); + + DeclarationNameInfo DNI = FDDef->getNameInfo(); + std::string MatchedName = DNI.getAsString(); + + /*going through the already matched functions,making sure we are not adding duplicates.*/ + for (unsigned x = 0; x < VecC; ++x) + { + if (FuncScopeProto[x].FuncNameString == MatchedName && FuncScopeProto[x].DefinitionSL == FDSL.printToString(*MR.SourceManager)) + { + AlreadyTagged = true; + + if (FDDef->isExternC()) + { + if (FDDadFullSL.getFileID() != FDFullSL.getFileID()) + { + FuncScopeProto[x].hasExternalCall = true; + } + } + } + } + + if (AlreadyTagged == false && FDDef->isExternC()) + { + FuncScopeProto.push_back(FuncScope()); + FuncScopeProto[VecC].FuncNameString = MatchedName; + FuncScopeProto[VecC].DefinitionSL = FDSL.printToString(*MR.SourceManager); + FuncScopeProto[VecC].FuncScopeSL = FDSL; + FuncScopeProto[VecC].FuncScopeFSL = MR.Context->getFullLoc(FDSL); + + if (FDDef->isExternC()) + { + if (FDDadFullSL.getFileID() != FDFullSL.getFileID()) + { + FuncScopeProto[VecC].hasExternalCall = true; + } + } + + VecC++; + } + } + } + + virtual void onEndOfTranslationUnit() + { + for (unsigned x = 0; x < VecC; ++x) + { + if (FuncScopeProto[x].hasExternalCall == false) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, FuncScopeProto[x].FuncScopeFSL.isInSystemHeader(), FuncScopeProto[x].FuncScopeSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, FuncScopeProto[x].FuncScopeFSL.getManager().isInMainFile(FuncScopeProto[x].FuncScopeSL), FuncScopeProto[x].FuncScopeSL)) + { + std::cout << "8.11:" << "Function does not have any external calls but is not declared as static:"; + std::cout << FuncScopeProto[x].DefinitionSL << ":" << "\n"; + + XMLDocOut.XMLAddNode(FuncScopeProto[x].FuncScopeFSL, FuncScopeProto[x].FuncScopeSL, "8.11", "Function does not have any external calls but is not declared as static : "); + JSONDocOUT.JSONAddElement(FuncScopeProto[x].FuncScopeFSL, FuncScopeProto[x].FuncScopeSL, "8.11", "Function does not have any external calls but is not declared as static : "); + } + } + } + } + } + +private: + struct FuncScope { + std::string FuncNameString; + bool hasExternalCall = false; + std::string DefinitionSL; + SourceLocation FuncScopeSL; + FullSourceLoc FuncScopeFSL; + }; + + bool AlreadyTagged = false; + + unsigned VecC; + + std::vector FuncScopeProto; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-also flags the main.*/ +class MCFunction165 : public MatchFinder::MatchCallback +{ +public: + MCFunction165 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunction165") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("mcfunction165"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "16.5:" << "Function does not return anything but is missing the void keyword for the return type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.5", "Function does not return anything but is missing the void keyword for the return type : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.5", "Function does not return anything but is missing the void keyword for the return type : "); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCFunction1652 : public MatchFinder::MatchCallback +{ +public: + MCFunction1652 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunction1652") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("mcfunction1652"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SourceLocation SLE = FD->getBody()->getLocStart(); + CheckSLValidity(SLE); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + + std::string FunctionSigAsString = Rewrite.getRewrittenText(SR); + + DeclarationNameInfo DNI = FD->getNameInfo(); + + std::string NameAsString = DNI.getAsString(); + + size_t voidposition = FunctionSigAsString.find(NameAsString, 0U); + unsigned lengthofstring = NameAsString.length(); + size_t voidposition2 = FunctionSigAsString.find("void", voidposition + lengthofstring - 1U); + + if (voidposition2 == std::string::npos) + { + std::cout << "16.5:" << "Function does not take any parameters but is not using the void keyword:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.5", "Function does not take any parameters but is not using the void keyword : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.5", "Function does not take any parameters but is not using the void keyword : "); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-has false-positives*/ +class MCPointer171 : public MatchFinder::MatchCallback +{ +public: + MCPointer171 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcpointer171") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mcpointer171") ; + + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType QT = DRE->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + if (TP->isAnyPointerType()) + { + std::cout << "17.1:" << "Pointer arithmatic for non-array pointers:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "17.1", "Pointer arithmatic for non-array pointers : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "17.1", "Pointer arithmatic for non-array pointers : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-has a lot of false positives. now works based on array types not the array itself.*/ +class MCPointer1723 : public MatchFinder::MatchCallback +{ +public: + MCPointer1723 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcpointer1723rhs") != nullptr && MR.Nodes.getNodeAs("mcpointer1723lhs")) + { + const DeclRefExpr* DRER = MR.Nodes.getNodeAs("mcpointer1723rhs"); + const DeclRefExpr* DREL = MR.Nodes.getNodeAs("mcpointer1723lhs"); + const BinaryOperator* BO = MR.Nodes.getNodeAs("mcpointer1723daddy"); + + SourceLocation SL = BO->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType QTR = DRER->getType(); + QualType QTL = DREL->getType(); + + const clang::Type* TPR = QTR.getTypePtr(); + const clang::Type* TPL = QTL.getTypePtr(); + + if (TPR->getPointeeType() != TPL->getPointeeType()) + { + std::cout << "17.2 | 17.3:" << "Pointer-type operands to BinaryOperator dont point to the same array:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "17.2 | 17.3", "Pointer-type operands to BinaryOperator dont point to the same array : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "17.2 | 17.3", "Pointer-type operands to BinaryOperator dont point to the same array : "); + + /*@DEVI-FIXME-cant extract mutagen correctly*/ + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*BO), *MR.Context); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCPointer174 : public MatchFinder::MatchCallback +{ +public: + MCPointer174 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcpointer174") != nullptr) + { + const CastExpr* CE = MR.Nodes.getNodeAs("mcpointer174"); + + SourceLocation SL = CE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "17.4:" << "The only allowed form of pointer arithmetic is array indexing:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CE), *MR.Context); + } + } + } + } + + if (MR.Nodes.getNodeAs("mcpointer1742") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mcpointer1742"); + + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "17.4:" << "The only allowed form of pointer arithmetic is array indexing:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-in case of function pointers, where an argument has more than two levels of indirection, +the argument and the function pointer both get tagged. technically, it is a defendable interpretation of the rule.*/ +class MCPointer175 : public MatchFinder::MatchCallback +{ +public: + MCPointer175 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + const VarDecl* VD; + const FieldDecl* FD; + SourceLocation SL; + QualType QT; + + if (MR.Nodes.getNodeAs("mcpointer175") != nullptr) + { + VD = MR.Nodes.getNodeAs("mcpointer175"); + + SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QT = VD->getType(); + } + + if (MR.Nodes.getNodeAs("mcpointer175field") != nullptr) + { + FD = MR.Nodes.getNodeAs("mcpointer175field"); + + SL = FD->getSourceRange().getBegin(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QT = FD->getType(); + } + + + QualType CQT = QT.getCanonicalType(); + + std::string CQTAsString = CQT.getAsString(); + + const clang::Type* TP [[maybe_unused]] = CQT.getTypePtr(); + + unsigned starCounter = 0U; + size_t StarPos = 0U; + size_t OpenParens = 0U; + size_t NextOpenParens = 0U; + size_t CommaPos = 0U; + size_t NextCommaPos = 0U; + bool FoundAMatch [[maybe_unused]] = false; + + while (StarPos != std::string::npos) + { + StarPos = CQTAsString.find("*", StarPos + 1); + OpenParens = CQTAsString.find("(", NextOpenParens + 1); + CommaPos = CQTAsString.find(",", NextCommaPos + 1); + + if (OpenParens != std::string::npos) + { + if (StarPos > OpenParens) + { + starCounter = 0U; + NextOpenParens = OpenParens; + } + + } + + if (CommaPos != std::string::npos) + { + if (StarPos > CommaPos) + { + starCounter = 0U; + NextCommaPos = CommaPos; + } + } + + if (StarPos != std::string::npos) + { + starCounter++; + } + + if (starCounter >= 3U) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "17.5:" << "Pointer has more than 2 levels of indirection:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "17.5", "Pointer has more than 2 levels on indirection : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "17.5", "Pointer has more than 2 levels on indirection : "); + } + } + + break; + } + } + + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-the simple char type can be singed or unsigned. its implementation-defined. the values appear +folded on AST and currently i dont know of a method to differentiate between singed/unsigned char and simple char. +sure, we can get the text of the vardecl and do string search in there but that still does not solve our problem. +we could do string search for the RHS expression but thats limited and then there is flagging cases that are of char +type because of a macro expansion(the macro adding signed or unsinged to the char type). we could flag those macros +in a PPCallback::MacroDefined but that leaves us with the problem of CStyleCasts. for example when a +simple char type is assigned a numeric values cast explicitly cast to simple char, misra-c says it does not +break rule 6.1(see https://www.misra.org.uk/forum/viewtopic.php?t=1020 for reference). the bottom line is, +there is a way to implement this but the implementation will be janky and its too much trouble for a janky +implementation that later on will not be modifiable much.*/ +class MCTypes61 : public MatchFinder::MatchCallback +{ +public: + MCTypes61 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if ((MR.Nodes.getNodeAs("mctypes6rhs") != nullptr) \ + && (MR.Nodes.getNodeAs("mctypes6origin") != nullptr) \ + && (MR.Nodes.getNodeAs("mctypes6dous") != nullptr)) + { + const Expr* EXP = MR.Nodes.getNodeAs("mctypes6rhs"); + const VarDecl* VD = MR.Nodes.getNodeAs("mctypes6origin"); + + QualType QT = VD->getType(); + const clang::Type* TP = QT.getTypePtr(); + + QualType QTEXP = EXP->getType(); + const clang::Type* TPEXP = QTEXP.getTypePtr(); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SourceLocation SLE = EXP->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + +#if 0 + std::string RHSString = Rewrite.getRewrittenText(SR); + + //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << "\n"; + + size_t singleQuoteLoc = RHSString.find("'", 0U); + size_t doubleQuoteLoc = RHSString.find("\"", 0U); + size_t singleQuoteLocE = RHSString.rfind("'", 0U); + size_t doubleQuoteLocE = RHSString.rfind("\"", 0U); +#endif + + /*@DEVI-the logic here is that we know we have matched a chartype. if its not either a singedinteger or + unsingedinteger, then it is a simple char. otherwise it is signed or unsigned char.*/ +#if 1 + if (TP->isSignedIntegerType() || TP->isUnsignedIntegerType()) + { + //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << SL.printToString(*MR.SourceManager) << "\n"; + + if (!TPEXP->isSignedIntegerType() && !TPEXP->isUnsignedIntegerType()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "6.2:" << "Sgined or unsigned char type holds characterLiterals:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.2", "Sgined or unsigned char type holds characterLiterals : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.2", "Sgined or unsigned char type holds characterLiterals : "); + } + } + } + } + else + { + + } + + if (!TP->isSignedIntegerType() && !TP->isUnsignedIntegerType()) + { + //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << SL.printToString(*MR.SourceManager) << "\n"; + + if (TPEXP->isSignedIntegerType() || TPEXP->isUnsignedIntegerType()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "6.1:" << "Simple char type holds numeric values:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.1", "Simple char type holds numeric values : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.1", "Simple char type holds numeric values : "); + } + } + } + } +#endif + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCSU181 : public MatchFinder::MatchCallback +{ +public: + MCSU181 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcsu181arr") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("mcsu181arr"); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "18.1:" << "ArrayType incomplete at the end of the translation unit:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "18.1", "ArrayType incomplete at the end of the translation unit : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "18.1", "ArrayType incomplete at the end of the translation unit : "); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCPTC11CSTYLE : public MatchFinder::MatchCallback +{ +public: + MCPTC11CSTYLE (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcptc11cstyle") != nullptr) + { + const CStyleCastExpr* CSCE = MR.Nodes.getNodeAs("mcptc11cstyle"); + + SourceLocation SL = CSCE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + QualType QT = CSCE->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + ASTContext *const ASTC [[maybe_unused]] = MR.Context; + +#if 0 + const ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*CSCE); + + /*assumptions:implicitcastexpr does not have more than one parent in C.*/ + const ast_type_traits::DynTypedNode ParentNode = NodeList[0]; + + ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); + + std::string StringKind = ParentNodeKind.asStringRef().str(); +#endif + + CastKind CK = CSCE->getCastKind(); + + bool ShouldBeTagged11 = false; + + if (TP->isFunctionPointerType()) + { + if (((CK != CK_IntegralToPointer) && (CK != CK_PointerToIntegral) && \ + (CK != CK_LValueToRValue) && (CK != CK_FunctionToPointerDecay) && \ + (CK != CK_ArrayToPointerDecay))) + { + ShouldBeTagged11 = true; + } + + if (CK == CK_BitCast) + { + ShouldBeTagged11 = true; + } + + if (ShouldBeTagged11) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.1:" << "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.1", "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.1", "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); + } + } + } + } + } + + if ((CK == CK_IntegralToPointer) || (CK == CK_PointerToIntegral)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.3:" << "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.3", "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.3", "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); + } + } + } + } + + if (CK == CK_BitCast || CK == CK_PointerToBoolean || CK == CK_AnyPointerToBlockPointerCast) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "11.x:" << "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "11.x", "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "11.x", "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); + } + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCATC101 : public MatchFinder::MatchCallback +{ +public: + MCATC101 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("atcdaddy") != nullptr) + { + const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("atcdaddy"); + + if ((ICE->getCastKind() == CK_IntegralCast) || (ICE->getCastKind() == CK_FloatingCast) || \ + (ICE->getCastKind() == CK_FloatingComplexCast) || (ICE->getCastKind() == CK_IntegralComplexCast)) + { + SourceLocation SL = ICE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext *const ASTC = MR.Context; + + QualType QTDaddy = ICE->getType(); + QualType QTKiddy; + + if (MR.Nodes.getNodeAs("atcdous") != nullptr) + { + const BinaryOperator* ChildNode = MR.Nodes.getNodeAs("atcdous"); + QTKiddy = ChildNode->getType(); + } + + if (MR.Nodes.getNodeAs("atcuno") != nullptr) + { + const UnaryOperator* ChildNode = MR.Nodes.getNodeAs("atcuno"); + QTKiddy = ChildNode->getType(); + } + + if (MR.Nodes.getNodeAs("atcparens") != nullptr) + { + const ParenExpr* ChildNode = MR.Nodes.getNodeAs("atcparens"); + QTKiddy = ChildNode->getType(); + } + + if (MR.Nodes.getNodeAs("atckidice") != nullptr) + { + const ImplicitCastExpr* ChildNode = MR.Nodes.getNodeAs("atckidice"); + QTKiddy = ChildNode->getType(); + } + + if (MR.Nodes.getNodeAs("atccstyle") != nullptr) + { + const CStyleCastExpr* ChildNode = MR.Nodes.getNodeAs("atccstyle"); + QTKiddy = ChildNode->getType(); + } + + const clang::Type* TPDaddy = QTDaddy.getTypePtr(); + const clang::Type* TPChild = QTKiddy.getTypePtr(); + + const clang::Type* CanonTypeDaddy = ASTC->getCanonicalType(TPDaddy); + const clang::Type* CanonTypeChild = ASTC->getCanonicalType(TPChild); + + uint64_t ICETypeSize = ASTC->getTypeSize(CanonTypeDaddy); + uint64_t ChildTypeSize = ASTC->getTypeSize(CanonTypeChild); + + bool ICETypeIsSignedInt = CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Long) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Short) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::SChar) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_S) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::LongLong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int128) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_S); + bool ChildTypeIsSignedInt = CanonTypeChild->isSpecificBuiltinType(BuiltinType::Kind::Long) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Short) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::SChar) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_S) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::LongLong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int128) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_S); + + bool ICETypeIsUSignedInt = CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); + bool ChildTypeIsUSignedInt = CanonTypeChild->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ + CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); + + bool ICETypeIsInteger = ICETypeIsSignedInt || ICETypeIsUSignedInt; + bool ChildTypeIsInteger = ChildTypeIsSignedInt || ChildTypeIsUSignedInt; + + if (ICETypeIsInteger && ChildTypeIsInteger) + { + if ((ICETypeIsSignedInt && ChildTypeIsUSignedInt) || (ICETypeIsUSignedInt && ChildTypeIsSignedInt)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.1/2:" << "ImplicitCastExpr changes the signedness of the type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr changes the signedness of the type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr changes the signedness of the type: "); + } + } + } + } + + if (ICETypeSize < ChildTypeSize && !(CanonTypeChild->isComplexIntegerType() || CanonTypeChild->isComplexType())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.1/2:" << "ImplicitCastExpr is narrowing:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr is narrowing: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr is narrowing: "); + } + } + } + + if (CanonTypeChild->isComplexIntegerType()) + { + if (ICETypeSize > ChildTypeSize) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.3:" << "ImplicitCastExpr is widening for complex integer type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.3", "ImplicitCastExpr is widening for complex integer type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.3", "ImplicitCastExpr is widening for complex integer type: "); + } + } + } + + const ComplexType* ChildCPXType = CanonTypeChild->getAsComplexIntegerType(); + const ComplexType* DaddyCPXType = CanonTypeDaddy->getAsComplexIntegerType(); + + QualType DaddyCPXQT = DaddyCPXType->getElementType(); + QualType ChildCPXQT = ChildCPXType->getElementType(); + + const clang::Type* DaddyCPXElementType = DaddyCPXQT.getTypePtr(); + const clang::Type * ChildCPXElementType = ChildCPXQT.getTypePtr(); + + /* + bool IsSignedCPXDaddy = DaddyCPXElementType->getAsPlaceholderType()->isSignedInteger(); + bool IsSignedCPXChild = ChildCPXElementType->getAsPlaceholderType()->isSignedInteger(); + bool IsUnsignedCPXDaddy = DaddyCPXElementType->getAsPlaceholderType()->isUnsignedInteger(); + bool IsUnsignedCPXChild = ChildCPXElementType->getAsPlaceholderType()->isUnsignedInteger(); + */ + + bool IsSignedCPXDaddy = false; + bool IsUnsignedCPXDaddy = false; + if (DaddyCPXElementType) { + auto placeholderType = DaddyCPXElementType->getAsPlaceholderType(); + if (placeholderType) { + IsSignedCPXDaddy = placeholderType->isSignedInteger(); + IsUnsignedCPXDaddy = placeholderType->isUnsignedInteger(); + } + } + + bool IsSignedCPXChild = false; + bool IsUnsignedCPXChild = false; + if (ChildCPXElementType) { + auto placeholderType = ChildCPXElementType->getAsPlaceholderType(); + if (placeholderType) { + IsSignedCPXChild = placeholderType->isSignedInteger(); + IsUnsignedCPXChild = placeholderType->isUnsignedInteger(); + } + } + + if ((IsSignedCPXDaddy && IsUnsignedCPXChild) || (IsUnsignedCPXDaddy && IsSignedCPXChild)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.3:" << "ImplicitCastExpr changes the signedness of the complex integer type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.3", "ImplicitCastExpr changes the signedness of the complex integer type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.3", "ImplicitCastExpr changes the signedness of the complex integer type type: "); + } + } + } + } + + /*clang::Type::iSComplexIntegerType will not return true for the gnu extension of complex integers.*/ + if (!CanonTypeChild->isComplexIntegerType() && CanonTypeChild->isComplexType()) + { + if (ICETypeSize > ChildTypeSize) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "10.4:" << "ImplicitCastExpr is widening for complex float type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.4", "ImplicitCastExpr is widening for complex float type: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.4", "ImplicitCastExpr is widening for complex float type: "); + } + } + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCIdent51 : public MatchFinder::MatchCallback +{ +public: + MCIdent51 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("ident5nameddecl") != nullptr) + { + const NamedDecl* ND = MR.Nodes.getNodeAs("ident5nameddecl"); + + const IdentifierInfo *II = ND->getIdentifier(); + + SourceLocation SL = ND->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext *const ASTC = MR.Context; + + const IdentifierTable &IT = ASTC->Idents; + + if (II != nullptr) + { + StringRef IdentStringRef = II->getName(); + + for (auto &iter : IT) + { + /*@DEVI-only works for UTF-8. for larger sizes we need a multiple of 32. for UTF-16 we need to check against 64 and so on.*/ + if (IdentStringRef.str().size() >= 32U) + { + if ((iter.getValue()->getName().str().substr(0U, 32U) == IdentStringRef.str().substr(0U, 32U)) && (iter.getValue()->getName().str() != IdentStringRef.str())) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "5.1:" << "Identifier relies on the signifacance of more than 31 charcaters:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "5.1", "Identifier relies on the significance of more than 31 charcaters: "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "5.1", "Identifier relies on the significance of more than 31 charcaters: "); + } + } + } + } + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCDCDF87 : public MatchFinder::MatchCallback +{ +public: + MCDCDF87 (Rewriter &Rewrite) : Rewrite(Rewrite) + { + IsNewEntry = true; + } + + virtual void run(const MatchFinder::MatchResult &MR) + { + if ((MR.Nodes.getNodeAs("mcdcdfobj") != nullptr) \ + && (MR.Nodes.getNodeAs("mcdcdf87daddy") != nullptr) && \ + (MR.Nodes.getNodeAs("mcdcdf87origin") != nullptr)) + { + IsNewEntry = true; + + const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf87daddy"); + const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf87origin"); + + std::string VDName = VD->getIdentifier()->getName().str(); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + + for (auto &iter : MaybeLocalObjInfoProto) + { + if (iter.ObjNameStr == VDName && iter.ObjSL == SL) + { + IsNewEntry = false; + + if ((iter.FirstDaddyName != FD->getNameInfo().getAsString())) + { + iter.HasMoreThanOneDaddy = true; + } + } + } + + if (IsNewEntry) + { + MaybeLocalObjInfo Temp = {SL, ASTC->getFullLoc(SL), SL.printToString(*MR.SourceManager), VDName, FD->getNameInfo().getAsString(), false}; + MaybeLocalObjInfoProto.push_back(Temp); + } + } + } + + virtual void onEndOfTranslationUnit() + { + for (auto &iter : MaybeLocalObjInfoProto) + { + if (!iter.HasMoreThanOneDaddy) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, iter.ObjFSL.isInSystemHeader(), iter.ObjSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, iter.ObjFSL.getManager().isInMainFile(iter.ObjSL), iter.ObjSL)) + { + std::cout << "8.7:" << "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block:"; + std::cout << iter.ObjSLStr << ":" << "\n"; + + XMLDocOut.XMLAddNode(iter.ObjFSL, iter.ObjSL, "8.7", \ + "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block: "); + JSONDocOUT.JSONAddElement(iter.ObjFSL, iter.ObjSL, "8.7", \ + "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block: "); + } + } + } + } + } + + +private: + struct MaybeLocalObjInfo + { + MaybeLocalObjInfo(SourceLocation iObjSL, FullSourceLoc iObjFSL, std::string iObjSLStr, \ + std::string iObjNameStr, std::string iFirstDaddyName, bool iHasMoreThanOneDaddy = false) + { + ObjSL = iObjSL; + ObjFSL = iObjFSL; + ObjSLStr = iObjSLStr; + ObjNameStr = iObjNameStr; + FirstDaddyName = iFirstDaddyName; + HasMoreThanOneDaddy = iHasMoreThanOneDaddy; + } + + SourceLocation ObjSL; + FullSourceLoc ObjFSL; + std::string ObjSLStr; + std::string ObjNameStr; + std::string FirstDaddyName; + bool HasMoreThanOneDaddy = false; + }; + + bool IsNewEntry; + + std::vector MaybeLocalObjInfoProto; + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-has false positives will tag incomplete types if they are later declared as complete types.*/ +class [[maybe_unused]] MCDCDF88 : public MatchFinder::MatchCallback +{ +public: + MCDCDF88 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + bool IsNewEntry = true; + + if (MR.Nodes.getNodeAs("mcdcdf88var") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf88var"); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + const SourceManager &SM = FSL.getManager(); + + if (!SM.isInMainFile(SL)) + { + return void(); + } + + std::string NDNameString = VD->getNameAsString(); + + for (auto &iter : ExternObjInfoProto) + { +#if 0 + std::cout << "diagnostic2:" << "Variable:" << NDNameString << ":" << iter.XObjNameStr << "\n"; +#endif + if (iter.XObjNameStr == NDNameString) + { + IsNewEntry = false; + + iter.HasMoreThanOneDefinition = true; + } + } + + if (IsNewEntry) + { + const SourceManager &SM = FSL.getManager(); + + ExternObjInfo Temp = {FSL.getSpellingLineNumber(), FSL.getSpellingColumnNumber(), \ + SM.getFilename(SL), SL.printToString(*MR.SourceManager), NDNameString, \ + FSL.getFileID(), false, false, false + }; + ExternObjInfoProto.push_back(Temp); + } + } + + if (MR.Nodes.getNodeAs("mcdcdf88function") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf88function"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext* const ASTC = MR.Context; + + std::string NDNameString = FD->getNameAsString(); + + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + const SourceManager &SM = FSL.getManager(); + + if (!SM.isInMainFile(SL)) + { + return void(); + } + + for (auto &iter : ExternObjInfoProto) + { + if (iter.XObjNameStr == NDNameString) + { + IsNewEntry = false; + + + if ((iter.IsDefinition == true && FD->isThisDeclarationADefinition()) || (iter.IsDeclaration == true && !FD->isThisDeclarationADefinition())) + { + iter.HasMoreThanOneDefinition = true; + + if (FD->isThisDeclarationADefinition()) + { + iter.IsDefinition = true; + } + else + { + iter.IsDeclaration = true; + } + } + + } + } + + if (IsNewEntry) + { + ExternObjInfo Temp = {FSL.getSpellingLineNumber(), FSL.getSpellingColumnNumber(), \ + SM.getFilename(SL), SL.printToString(*MR.SourceManager), NDNameString, \ + FSL.getFileID(), false, FD->isThisDeclarationADefinition(), !FD->isThisDeclarationADefinition() + }; + ExternObjInfoProto.push_back(Temp); + } + } + } + +private: + /*@DEVI-the structure that holds the values is global since we need it to survive through all the TUs.*/ + + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/*@DEVI-ASTContext doesn not have all the comments in a source file. i dunno why.*/ +class MCLangX23 : public MatchFinder::MatchCallback +{ +public: + MCLangX23 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mclangx23") != nullptr) + { + ASTContext *const ASTC = MR.Context; + + const SourceManager &SM = ASTC->getSourceManager(); + + RawCommentList RCL = ASTC->Comments; + + ArrayRef RawCommentArrRef = RCL.getComments(); + + std::string RawText; + + size_t matchLoc; + + unsigned currentLoc = 1U; + + unsigned MatchCounter = 0U; + + for (auto &iter : RawCommentArrRef) + { + RawText = iter->getRawText(SM); + + SourceLocation RCSL = iter->getLocStart(); + CheckSLValidity(RCSL); + RCSL = Devi::SourceLocationHasMacro(RCSL, Rewrite, "start"); + + while (true) + { + matchLoc = RawText.find("/*", currentLoc); + + if (matchLoc != std::string::npos) + { + currentLoc = matchLoc + 1U; + + MatchCounter++; + } + else + { + break; + } + } + + currentLoc = 1U; + + if (!once) + { + if (MatchCounter >= 1U) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, RCSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, RCSL)) + { + std::cout << "2.3:" << "character sequence \"/*\" used inside the comment:"; + std::cout << RCSL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, RCSL, "2.3", "character sequence \"/*\" used inside the comment : "); + JSONDocOUT.JSONAddElement(MR.Context, RCSL, "2.3", "character sequence \"/*\" used inside the comment : "); + } + } + } + } + + MatchCounter = 0U; + } + + once = true; + + } + } + +private: + bool once = false; + Rewriter &Rewrite [[maybe_unused]]; +}; +/**********************************************************************************************************************/ +/*@DEVI-changes done to the pointee through unaryOperators ++ and -- will not be tagged by this class. +see implementation notes for the explanation.*/ +class MCFunction167 : public MatchFinder::MatchCallback +{ +public: + MCFunction167 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcfunction167") != nullptr) + { + const ParmVarDecl* PVD = MR.Nodes.getNodeAs("mcfunction167"); + + SourceLocation SL = PVD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + QualType QT = PVD->getOriginalType(); + + ASTContext *const ASTC [[maybe_unused]] = MR.Context; + + if (!QT.isConstQualified()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "16.7:" << "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "16.7", "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const : "); + JSONDocOUT.JSONAddElement(MR.Context, SL, "16.7", "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const : "); + } + } + } + } + } + } + +private: + Rewriter &Rewrite [[maybe_unused]]; +}; +/**********************************************************************************************************************/ +/*@DEVI-the match is quite simplistic. we could match for chartypes appearing as the LHS and then check the type of +the RHS expr but that leaves pointers changing the value.*/ +class MCTypes612 : public MatchFinder::MatchCallback +{ +public: + MCTypes612 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mc612exp") != nullptr) + { + bool RHSIsCharLit = false; + bool RHSIsIntLit = false; + + const Expr* LHS = MR.Nodes.getNodeAs("mc612exp"); + + if (MR.Nodes.getNodeAs("mc612charlit") != nullptr) + { + RHSIsCharLit = true; + } + + if (MR.Nodes.getNodeAs("mc612intlit") != nullptr) + { + RHSIsIntLit = true; + } + + SourceLocation SL = LHS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + QualType QT = LHS->getType(); + const clang::Type* TP = QT.getTypePtr(); + + ASTContext *const ASTC = MR.Context; + + const clang::Type* CanonTP = ASTC->getCanonicalType(TP); + + /*checking whether the unqualified type is simple char*/ + if (CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_S)) + { + if (RHSIsIntLit) + { + std::cout << "6.1:" << "Simple char type should only hold character values:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.1", "Simple char type should only hold character values:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.1", "Simple char type should only hold character values:"); + } + } + + if (CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UChar) || CanonTP->isSpecificBuiltinType(BuiltinType::Kind::SChar)) + { + if (RHSIsCharLit) + { + std::cout << "6.2:" << "Signed or unsigned char type should only hold numeric values:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "6.2", "Signed or unsigned char type should only hold numeric values:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "6.2", "Signed or unsigned char type should only hold numeric values:"); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCF143 : public MatchFinder::MatchCallback +{ +public: + MCCF143 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccf143nullstmt") != nullptr) + { + const NullStmt* NS = MR.Nodes.getNodeAs("mccf143nullstmt"); + + SourceLocation SL = NS->getSemiLoc(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + ASTContext *const ASTC = MR.Context; + + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + const SourceManager &SM = FSL.getManager(); + + StringRef FileNameString = SM.getFilename(SL); + + NullStmtInfo Temp = {FSL.getSpellingColumnNumber(), FSL.getSpellingLineNumber(), FileNameString, SM.isInMainFile(SL), SM.isInSystemHeader(SL)}; + + NullStmtProto.push_back(Temp); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr1212 : public MatchFinder::MatchCallback +{ +public: + MCExpr1212 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr1212") != nullptr) + { + const RecordDecl* RD = MR.Nodes.getNodeAs("mcexpr1212"); + + SourceLocation SL = RD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + std::cout << "12.12:" << "Possible violation of 12.12-access to the underlying bit representation of a floating type:"; + std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.12", "Possible violation of 12.12-access to the underlying bit representation of a floating type:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.12", "Possible violation of 12.12-access to the underlying bit representation of a floating type:"); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCExpr1211 : public MatchFinder::MatchCallback +{ +public: + MCExpr1211 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcexpr1211") != nullptr) + { + const Expr* EXP = MR.Nodes.getNodeAs("mcexpr1211"); + + SourceLocation SL = EXP->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + SourceLocation SLE = EXP->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + + std::string targetExpr = Rewrite.getRewrittenText(SR); + + ASTContext *const ASTC = MR.Context; + + QualType QT = EXP->getType(); + + const clang::Type* TP = QT.getTypePtr(); + + const clang::Type* CanonTP = ASTC->getCanonicalType(TP); + + bool TypeIsUSignedInt = CanonTP->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ + CanonTP->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); + +#if 0 + bool TypeIsUSignedInt = false; + if (CanonTP) { + auto placeholderType = CanonTP->getAsPlaceholderType(); + if (placeholderType) { + TypeIsUSignedInt = placeholderType->isUnsignedInteger(); + } + } +#endif + + if (TypeIsUSignedInt) + { + int64_t UnoFinal = 0; + int64_t DousFinal = 0; + bool MatchedUno = false; + bool MatchedDous = false; + + /*@DEVI-compilers that actually treat post and pre inc or dec need more. this doesnt support that.*/ + if (MR.Nodes.getNodeAs("mcexpr1211uno") != nullptr) + { + MatchedUno = true; + + const UnaryOperator* UO = MR.Nodes.getNodeAs("mcexpr1211uno"); + + clang::UnaryOperator::Opcode UnoOpKind = UO->getOpcode(); + + const Expr* UnoSubEXP = UO->getSubExpr(); + + llvm::APSInt UnoResult; + + UnoFinal = UnoResult.getExtValue(); + + if (UnoSubEXP->EvaluateAsInt(UnoResult, *ASTC)) + { + if (UnoOpKind == UO_PostInc || UnoOpKind == UO_PreInc) + { + UnoFinal++; + } + else if (UnoOpKind == UO_PostDec || UnoOpKind == UO_PreDec) + { + UnoFinal--; + } + else + { + /*intentionally left blank. we cant get anything else. were only matching for these two unaryoperators.*/ + } + } + } + + if (MR.Nodes.getNodeAs("mcexpr1211dous") != nullptr) + { + MatchedDous = true; + + const BinaryOperator* BO = MR.Nodes.getNodeAs("mcexpr1211dous"); + + clang::BinaryOperator::Opcode DousOpKind = BO->getOpcode(); + + const Expr* DousLHS = BO->getLHS(); + const Expr* DousRHS = BO->getRHS(); + + llvm::APSInt DousLHSAPS; + llvm::APSInt DousRHSAPS; + + if (DousLHS->EvaluateAsInt(DousLHSAPS, *ASTC) && DousRHS->EvaluateAsInt(DousRHSAPS, *ASTC)) + { + int64_t DousLHSInt64 = DousLHSAPS.getExtValue(); + int64_t DousRHSInt64 = DousRHSAPS.getExtValue(); + + switch (DousOpKind) + { + case BO_Add: + DousFinal = DousRHSInt64 + DousLHSInt64; + break; + case BO_Sub: + DousFinal = DousRHSInt64 - DousLHSInt64; + break; + case BO_Div: + DousFinal = DousRHSInt64 / DousLHSInt64; + break; + case BO_Mul: + DousFinal = DousRHSInt64 * DousLHSInt64; + break; + default: + /*cant really happen, were not matching anything else.*/ + break; + } + } + } + + llvm::APSInt OverflowCondidate; + + EXP->EvaluateAsInt(OverflowCondidate, *ASTC); + + int64_t IntExprValue = OverflowCondidate.getExtValue(); + + if ((MatchedDous && (DousFinal != IntExprValue)) || (MatchedUno && (UnoFinal != IntExprValue))) + { + std::cout << "12.11" << ":" << "Constant Unsinged Expr evaluation resuslts in an overflow:" << SL.printToString(*MR.SourceManager) << ":" << IntExprValue << " " << DousFinal << " " << ":" << targetExpr << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "12.11", "Constant Unsinged Expr evaluation resuslts in an overflow:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "12.11", "Constant Unsinged Expr evaluation resuslts in an overflow:"); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCATC105 : public MatchFinder::MatchCallback +{ +public: + MCATC105 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mcatc105lhs") != nullptr) + { + bool ShouldBeTagged = false; + SourceLocation SL; + const Expr* IgnoreImplicitEXP; + ast_type_traits::DynTypedNode DynOpNode; + + if (MR.Nodes.getNodeAs("mcatc105") != nullptr) + { + const BinaryOperator* BO = MR.Nodes.getNodeAs("mcatc105"); + DynOpNode = ast_type_traits::DynTypedNode::create(*BO); + + SL = BO->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + if (MR.Nodes.getNodeAs("mcatc105uno") != nullptr) + { + const UnaryOperator* UO = MR.Nodes.getNodeAs("mcatc105uno"); + DynOpNode = ast_type_traits::DynTypedNode::create(*UO); + + SL = UO->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + } + + const Expr* EXP = MR.Nodes.getNodeAs("mcatc105lhs"); + IgnoreImplicitEXP = EXP->IgnoreImpCasts(); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + ASTContext *const ASTC = MR.Context; + + const TargetInfo &TI = ASTC->getTargetInfo(); + + unsigned int ShortSize = TI.getShortWidth(); + + QualType QT = IgnoreImplicitEXP->getType(); + const clang::Type* TP = QT.getTypePtr(); + + const clang::Type* CanonTP = ASTC->getCanonicalType(TP); + + if (CanonTP->isUnsignedIntegerType() || CanonTP->isSignedIntegerType() || CanonTP->isAnyCharacterType()) + { + + /*@DEVI-assumptions:nothing has more than one parent in C.*/ + if (ShortSize == ASTC->getTypeSize(QT) || 8U == ASTC->getTypeSize(QT)) + { + /*@DEVI-assumes there is only one parent for every node which is true only for C, not Cpp*/ + ASTContext::DynTypedNodeList NodeList = ASTC->getParents(DynOpNode); + ast_type_traits::DynTypedNode ParentNode; + if (!NodeList.empty()) ParentNode = NodeList[0U]; + else return void(); + + ASTContext::DynTypedNodeList AncestorNodeList = ASTC->getParents(ParentNode); + + ast_type_traits::DynTypedNode AncestorNode; + if (!AncestorNodeList.empty()) AncestorNode = AncestorNodeList[0U]; + else return void(); + + ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); + ast_type_traits::ASTNodeKind AncestorNodeKind = AncestorNode.getNodeKind(); + + std::string ParentStringKind = ParentNodeKind.asStringRef().str(); + std::string AncestorStringKind = AncestorNodeKind.asStringRef().str(); + + if (ParentStringKind == "CStyleCastExpr") + { + const CStyleCastExpr* CSCE = ParentNode.get(); + + if (CSCE->getType() != QT) + { + ShouldBeTagged = true; + } + } + else if (ParentStringKind == "ParenExpr" && AncestorStringKind == "CStyleCastExpr") + { + const CStyleCastExpr* CSCE = AncestorNode.get(); + + if (CSCE->getType() != QT) + { + ShouldBeTagged = true; + } + } + else + { + ShouldBeTagged = true; + } + + if (ShouldBeTagged) + { + std::cout << "10.5" << ":" << "Result of operands << or ~ must be explicitly cast to the type of the expression:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "10.5", "Result of operands << or ~ must be explicitly cast to the type of the expression:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "10.5", "Result of operands << or ~ must be explicitly cast to the type of the expression:"); + + if (mutagen) + { + ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); + } + } + } + } + +#if 0 + const BuiltinType* BT = CanonTP->getAsPlaceholderType(); + const LangOptions &LO = ASTC->getLangOpts(); + std::string something = TypeName::getFullyQualifiedName(QT, *ASTC, true); + StringRef BTName = BT->getName(PrintingPolicy(LO)); +#endif + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCCSE135 : public MatchFinder::MatchCallback +{ +public: + MCCSE135 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mccse135") != nullptr) + { + const ForStmt* FS = MR.Nodes.getNodeAs("mccse135"); + + SourceLocation SL = FS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + ASTContext *const ASTC = MR.Context; + + const Expr* FSCond = FS->getCond(); + const Expr* FSInc = FS->getInc(); + const Stmt* FSInit = FS->getInit(); + + bool CondPresent = (FSCond != nullptr); + bool DIncPresent = (FSInc != nullptr); + bool InitPresent = (FSInit != nullptr); + + /*@DEVI-for the third one we are not checking to see whether the loop counter has been previously initialized.*/ + if (!((CondPresent && DIncPresent && InitPresent) || (!CondPresent && !DIncPresent && !InitPresent) || (CondPresent && DIncPresent && !InitPresent))) + { + std::cout << "13.5" << ":" << "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:"); + } + + if (FSInc != nullptr) + { + if (!FSInc->HasSideEffects(*ASTC, true)) + { + std::cout << "13.5" << ":" << "The increment expression in the ForStmt has no side-effects:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The increment expression in the ForStmt has no side-effects:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The increment expression in the ForStmt has no side-effects:"); + } + } + + if (FSCond != nullptr) + { + if (FSCond->HasSideEffects(*ASTC, true)) + { + std::cout << "13.5" << ":" << "The condition expression in the ForStmt has side-effect:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The condition expression in the ForStmt has side-effect:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The condition expression in the ForStmt has side-effect:"); + } + + if (!FSCond->isKnownToHaveBooleanValue()) + { + std::cout << "13.5" << ":" << "The expression in the ForStmt condition does not return a boolean:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The expression in the ForStmt condition does not return a boolean:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The expression in the ForStmt condition does not return a boolean:"); + } + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCConst71 : public MatchFinder::MatchCallback +{ +public: + MCConst71 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + std::string TagCandidateString; + SourceLocation SL; + + if (MR.Nodes.getNodeAs("mcconst71int") != nullptr) + { + const IntegerLiteral* IL = MR.Nodes.getNodeAs("mcconst71int"); + + SourceRange SR; + SL = IL->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SR.setBegin(SL); + SourceLocation SLE = IL->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); + SR.setEnd(SLE); + + TagCandidateString = Rewrite.getRewrittenText(SR); + } + + if (MR.Nodes.getNodeAs("mcconst71string") != nullptr) + { + const clang::StringLiteral* StringLit = MR.Nodes.getNodeAs("mcconst71string"); + + SL = StringLit->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "strat"); + + TagCandidateString = StringLit->getString().str(); + } + + if (MR.Nodes.getNodeAs("mcconst71char") != nullptr) + { + const CharacterLiteral* CL = MR.Nodes.getNodeAs("mcconst71char"); + + SL = CL->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + SourceRange SR; + SourceLocation SLE = CL->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); + SR.setBegin(SL); + SR.setEnd(SLE); + + TagCandidateString = Rewrite.getRewrittenText(SR); + } + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::regex octalconstant("\\\\[0-7]+"); + std::regex octalconstantint("^0[0-9]+$"); + std::regex hexescapesequence("\\\\x[0-9a-fA-F]+"); + std::regex otherescapesequence("\\\\[^0-9abfnrtvx'\"\\?]"); + + std::smatch result; + +#if 0 + std::cout << "diagnostic2:" << TagCandidateString << ":" << SL.printToString(*MR.SourceManager) << ":" << std::regex_search(TagCandidateString, result, octalconstant) << "\n"; +#endif + + if (std::regex_search(TagCandidateString, result, octalconstant) || std::regex_search(TagCandidateString, result, octalconstantint)) + { + std::cout << "7.1" << ":" << "Octal escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "7.1", "Octal escape sequence used:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "7.1", "Octal escape sequence used:"); + } + + if (std::regex_search(TagCandidateString, result, hexescapesequence)) + { + std::cout << "4.1" << ":" << "Hexadecimal escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "4.1", "Hexadecimal escape sequence used:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "4.1", "Hexadecimal escape sequence used:"); + } + + if (std::regex_search(TagCandidateString, result, otherescapesequence)) + { + std::cout << "4.1" << ":" << "Non-standard escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "4.1", "Non-standard escape sequence used:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "4.1", "Non-standard escape sequence used:"); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MCIdent5x : public MatchFinder::MatchCallback +{ +public: + MCIdent5x (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("ident5typedef") != nullptr) + { + const TypedefDecl* BN = MR.Nodes.getNodeAs("ident5typedef"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name = II->getName().str(); + + SourceManager *const SM = MR.SourceManager; + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::TypedefDecl, \ + false, Devi::FunctionDeclKind::NoValue, Devi::Scope::TU, "", true, false + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5record") != nullptr) + { + const RecordDecl* BN = MR.Nodes.getNodeAs("ident5record"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::RecordDecl, \ + BN->getTypeForDecl()->isIncompleteType(), Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5field") != nullptr) + { + const FieldDecl* BN = MR.Nodes.getNodeAs("ident5field"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::FieldDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false + }; + + IdentInfoProto.push_back(Temp); + } + + /*@DEVI-dunno how it will handle incomplete records passed as parmvars.*/ + if (MR.Nodes.getNodeAs("ident5parmvar") != nullptr) + { + const ParmVarDecl* BN = MR.Nodes.getNodeAs("ident5parmvar"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::ParmVarDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, BN->isStaticLocal() + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5func") != nullptr) + { + const FunctionDecl* BN = MR.Nodes.getNodeAs("ident5func"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + Devi::FunctionDeclKind tempfkind; + + if (BN->isThisDeclarationADefinition()) + { + tempfkind = Devi::FunctionDeclKind::Definition; + } + else + { + tempfkind = Devi::FunctionDeclKind::Declaration; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::FunctionDecl, \ + false, tempfkind, Devi::Scope::TU, "", true, false + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5var") != nullptr) + { + const VarDecl* BN = MR.Nodes.getNodeAs("ident5var"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::VarDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, BN->isStaticLocal() + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5enum") != nullptr) + { + const EnumDecl* BN = MR.Nodes.getNodeAs("ident5enum"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::EnumDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5label") != nullptr) + { + const LabelDecl* BN = MR.Nodes.getNodeAs("ident5label"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::LabelDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false + }; + + IdentInfoProto.push_back(Temp); + } + + if (MR.Nodes.getNodeAs("ident5enumconst") != nullptr) + { + const EnumConstantDecl* BN = MR.Nodes.getNodeAs("ident5enumconst"); + + SourceLocation SL = BN->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const IdentifierInfo* II = BN->getIdentifier(); + + std::string Name; + + if (II != nullptr) + { + Name = II->getName().str(); + } + + SourceManager *const SM = MR.SourceManager; + + std::string FunctionName; + + if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) + { + const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); + + FunctionName = FD->getNameAsString(); + } + + Devi::Scope tempscope = Devi::Scope::TU; + + if (FunctionName != "") + { + tempscope = Devi::Scope::Block; + } + + IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ + SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::EnumConstDecl, \ + false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false + }; + + IdentInfoProto.push_back(Temp); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/** + * @brief Tags all array declarations and uses of arrays through indexes. + */ +class SFCPPARR01 : public MatchFinder::MatchCallback +{ + public: + SFCPPARR01 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + /** + * @brief The virtual method that runs the tagging. + * + * @param MR MatchFinder::MatchResulet + */ + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("sfcpparrdecl") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("sfcpparrdecl"); + + SourceLocation SL = VD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "SaferCPP01" << ":" << "Native CPP array declared:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array declared:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP array declared:"); + } + + if (MR.Nodes.getNodeAs("sfcpparrcastexpr") != nullptr) + { + const CastExpr* CS = MR.Nodes.getNodeAs("sfcpparrcastexpr"); + + SourceLocation SL = CS->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "SaferCPP01" << ":" << "Native CPP array used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array used"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP arry=ay used"); + } + + if (MR.Nodes.getNodeAs("sfcpparrfield") != nullptr) + { + const FieldDecl* FD = MR.Nodes.getNodeAs("sfcpparrfield"); + + SourceLocation SL = FD->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "SaferCPP01" << ":" << "Native CPP array field used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array field used"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP arryay field used"); + } + } + + private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/** + * @brief The matcher run by SFCPPARR02. This ones does all the real tagging. + */ +class SFCPPARR02SUB : public MatchFinder::MatchCallback +{ + public: + SFCPPARR02SUB (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("sfcpp02sub") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpp02sub"); + + SourceManager *const SM = MR.SourceManager; + + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + //SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SL = SM->getSpellingLoc(SL); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + const NamedDecl* ND = DRE->getFoundDecl(); + + SourceLocation OriginSL = ND->getLocStart(); + CheckSLValidity(OriginSL); + //OriginSL = Devi::SourceLocationHasMacro(OriginSL, Rewrite, "start"); + OriginSL = SM->getSpellingLoc(OriginSL); + + StringRef OriginFileName [[maybe_unused]] = SM->getFilename(OriginSL); + +#if 0 + std::cout << "GarbageOut" << ":" << "Origin:" << DRE->getFoundDecl()->getName().str() << "\n"; + std::cout << "GarbageOut" << ":" << "Origin:" << ExtOriginFileName.str() << ":" << "Proto:" << OriginFileName.str() << "\n"; + std::cout << "GarbageOut" << ":" << "Origin:" << ExtOriginSL.printToString(*SM) << ":" << "Proto:" << OriginSL.printToString(*SM) << "\n"; +#endif + + if (OriginSL == ExtOriginSL && OriginFileName == ExtOriginFileName) + { + std::cout << "SaferCPP01" << ":" << "Native Array used - pointer points to an array:" << SL.printToString(*MR.SourceManager) << ":" << DRE->getFoundDecl()->getName().str() << "\n"; + } + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native Array used - pointer points to an array:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native Array used - pointer points to an array:"); + } + } + + void setOriginSourceLocation(SourceLocation inSL) + { + ExtOriginSL = inSL; + } + + void setOriginFileName(StringRef inStrRef) + { + ExtOriginFileName = inStrRef; + } + + private: + Rewriter &Rewrite [[maybe_unused]]; + SourceLocation ExtOriginSL; + StringRef ExtOriginFileName; +}; +/**********************************************************************************************************************/ +/** + * @brief MatchCallback for safercpp matching of pointers pointing to arrays. + */ +class SFCPPARR02 : public MatchFinder::MatchCallback +{ + public: + SFCPPARR02 (Rewriter &Rewrite) : Rewrite(Rewrite), SubHandler(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("sfcpparrdeep") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpparrdeep"); + + ASTContext *const ASTC = MR.Context; + + SourceManager *const SM = MR.SourceManager; + + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + SL = SM->getSpellingLoc(SL); + + const NamedDecl* ND = DRE->getFoundDecl(); + + StringRef NDName = ND->getName(); + + SubHandler.setOriginSourceLocation(SM->getSpellingLoc(ND->getLocStart())); + SubHandler.setOriginFileName(SM->getFilename(SM->getSpellingLoc(ND->getLocStart()))); + + Matcher.addMatcher(declRefExpr(to(varDecl(hasName(NDName.str())))).bind("sfcpp02sub"), &SubHandler); + + Matcher.matchAST(*ASTC); + +#if 0 + std::cout << "GarbageOutOrigin" << ":" << "GarbageOutOrigin:" << SL.printToString(*MR.SourceManager) << ":" << NDName.str() << "\n"; +#endif + } + } + + private: + Rewriter &Rewrite [[maybe_unused]]; + MatchFinder Matcher; + SFCPPARR02SUB SubHandler; +}; +/**********************************************************************************************************************/ +/** + * @brief The callback for the Safercpp pointer matchers. Matches the dedlarations. + */ +class SFCPPPNTR01 : public MatchFinder::MatchCallback +{ + public: + SFCPPPNTR01 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("sfcpppntr01") != nullptr) + { + const VarDecl* VD = MR.Nodes.getNodeAs("sfcpppntr01"); + + SourceLocation SL = VD->clang::Decl::getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "SaferCPP02" << ":" << "Native pointer declared:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP02", "Native pointer declared:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP02", "Native pointer declared:"); + } + } + + private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/** + * @brief The callback for the Safercpp pointer matchers. Matches the DeclRefExprs. + */ +class SFCPPPNTR02 : public MatchFinder::MatchCallback +{ + public: + SFCPPPNTR02 (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("sfcpppntr02") != nullptr) + { + const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpppntr02"); + + SourceLocation SL = DRE->getLocStart(); + CheckSLValidity(SL); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) + { + return void(); + } + + std::cout << "SaferCPP02" << ":" << "Native pointer used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; + + XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP02", "Native pointer used:"); + JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP02", "Native pointer used:"); + } + } + + private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +/*the sourcelocation used in the overload of XMLAddNode that takes sourcemanager as input parameter uses +the spelling location so the client does not need to check the sourcelocation for macros expansions.*/ +class PPInclusion : public PPCallbacks +{ +public: + explicit PPInclusion (SourceManager *SM) : SM(*SM) {} + + /*@DEVI-if we dont throw an exception for a bad header inclusion, we wil crash later on since we have InclusionDirective PPCallback.*/ + virtual bool FileNotFound(StringRef FileName, SmallVectorImpl &RecoveryPath) + { + std::cerr << "\033[1;31mHeader Not Found: " << FileName.str() << "\033[0m" << "\n"; +#if 0 + std::abort(); +#endif + throw MutExHeaderNotFound(FileName.str()); + } + + virtual void InclusionDirective (SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, \ + bool IsAngled, CharSourceRange FileNameRange, const FileEntry* File, \ + StringRef SearchPath, StringRef RelativePath, const clang::Module* Imported) + { + + CheckSLValidity(HashLoc); + +#if defined(__linux__) + std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); + std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); +#elif defined(__MACH__) && defined(__APPLE__) + std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); + std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); +#elif defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) + std::ifstream HeaderABS(SearchPath.str() + "\\" + FileName.str()); + std::ifstream HeaderRel(RelativePath.str() + "\\" + FileName.str()); +#else + std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); + std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); +#endif + + if (File->isValid() && (HeaderABS.good() || HeaderRel.good())) + { +#if 0 + assert(HashLoc.isValid() && "The SourceLocation for InclusionDirective is invalid."); +#endif + +#if 1 + if (IsAngled) + { + size_t singleQPos = FileName.find("\'", 0); + size_t doubleQPos = FileName.find("\"", 0); + size_t whateverSlashPos = FileName.find("\\", 0); + size_t commentPos = FileName.find("\\*", 0); + + if (singleQPos != std::string::npos || doubleQPos != std::string::npos || whateverSlashPos != std::string::npos || commentPos != std::string::npos) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "19.2:" << "illegal characters in inclusion directive:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); + } + } + } + + if (FileName == "errno.h") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "20.5:" << "errno shall not be used:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "20.5", "errno shall not be used : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "20.5", "errno shall not be used : "); + } + } + } + + if (FileName == "time.h") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "20.12:" << "stdlib time.h is included in the project. use is forbidden:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "20.12", "stdlib time.h is included in the project. use is forbidden : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "20.12", "stdlib time.h is included in the project. use is forbidden : "); + } + } + } + + if (FileName == "stdio.h") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "20.9:" << "stdlib stdio.h is included in the project. use is forbidden:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "20.9", "stdlib stdio.h is included in the project. use is forbidden : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "20.9", "stdlib stdio.h is included in the project. use is forbidden : "); + } + } + } + + if (FileName == "signal.h") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "20.8:" << "stdlib signal.h is included in the project. use is forbidden:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "20.8", "stdlib signal.h is included in the project. use is forbidden : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "20.8", "stdlib signal.h is included in the project. use is forbidden : "); + } + } + } + } + else + { + size_t singleQPos = FileName.find("\'", 0); + size_t whateverSlashPos = FileName.find("\\", 0); + size_t commentPos = FileName.find("\\*", 0); + + if (singleQPos != std::string::npos || whateverSlashPos != std::string::npos || commentPos != std::string::npos) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "19.2:" << "illegal characters in inclusion directive:"; + std::cout << HashLoc.printToString(SM) << "\n" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); + } + } + } + + bool IsNewIncludeFile = true; + + for (unsigned x = 0; x < IncludeFileArr.size(); ++x) + { + if (SearchPath.str() + "/" + FileName.str() == IncludeFileArr[x]) + { + IsNewIncludeFile = false; + break; + } + } + + /*its supposed to supprt linux and cygwin,mingw and mac builds.*/ + if (IsNewIncludeFile) + { +#if defined(__linux__) + IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); +#elif defined(__MACH__) && defined(__APPLE__) + IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); +#elif defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) + IncludeFileArr.push_back(SearchPath.str() + "\\" + FileName.str()); +#else + IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); +#endif + } + } + + size_t whateverSlashPos = FileName.find("\\", 0); + size_t theotherSlashPos = FileName.find(" / ", 0); + + if (whateverSlashPos != std::string::npos || theotherSlashPos != std::string::npos) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) + { + std::cout << "19.3:" << "Include directive contains file address, not just name:"; + std::cout << HashLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, HashLoc, "19.3", "Include directive contains file address, not just name : "); + JSONDocOUT.JSONAddElement(SM, HashLoc, "19.3", "Include directive contains file address, not just name : "); + } + } + } +#endif + } + } + + /*@DEVI-if the macro is not checked for being defined before almost any kind of use, the code will break in seemingly random ways.*/ + /*@DEVI-FIXME-the macro definition is the definition of the macro passed to defined. not sure what happens if there are more than two. + basically i dont know how to just get the tokens after defined.*/ + virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) + { +#if 1 + SourceLocation SL [[maybe_unused]] = Range.getBegin(); + CheckSLValidity(SL); + +#if 0 + assert(SL.isValid(), "the SourceLocation for macro Defined is not valid."); +#endif + + const MacroInfo* MI = MD.getMacroInfo(); + + DefMacroDirective* DMD = MD.getLocalDirective(); + + bool ShouldBeTagged194 = false; + +#if 1 + if (DMD) + { + if (DMD->isDefined()) + { + if (!MI->tokens_empty()) + { + ArrayRef TokenArrayRef = MI->tokens(); + + unsigned NumOfTokens = MI->getNumTokens(); + + if (NumOfTokens == 1U) + { + if (!(TokenArrayRef[0].getKind() == tok::identifier)) + { + ShouldBeTagged194 = true; + } + } + else if (NumOfTokens == 3U) + { + if (!(TokenArrayRef[0].getKind() == tok::l_paren && TokenArrayRef[1].getKind() == tok::identifier && TokenArrayRef[2].getKind() == tok::r_paren)) + { + ShouldBeTagged194 = true; + } + } + else + { + ShouldBeTagged194 = true; + } + } + else + { + ShouldBeTagged194 = true; + } + + if (ShouldBeTagged194) + { +#if 0 + std::cout << "19.14 : " << "Illegal \"defined\" form : " << "\n"; + std::cout << SL.printToString(SM) << "\n" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.14", "Illegal \"defined\" form : "); +#endif + } + } + } +#endif +#endif + } + + virtual void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef) + { +#if 1 + const MacroInfo* MI = MD.getMacroInfo(); + + DefMacroDirective* DMD = MD.getLocalDirective(); + + if (MI != nullptr && DMD != nullptr) + { + SourceLocation SL = MacroNameTok.getLocation(); + CheckSLValidity(SL); + +#if 0 + assert(SL.isValid(), "the SourceLocation for MacroUndefined is not valid."); +#endif + + /*start of 20.1*/ + /*inline and restrict are C99*/ + if (MacroNameTok.isOneOf(tok::kw_auto, tok::kw_break, tok::kw_case, tok::kw_char, tok::kw_const, tok::kw_continue, \ + tok::kw_default, tok::kw_do, tok::kw_double, tok::kw_else, tok::kw_enum, tok::kw_extern, \ + tok::kw_float, tok::kw_for, tok::kw_goto, tok::kw_if, tok::kw_inline, tok::kw_int, tok::kw_long, \ + tok::kw_register, tok::kw_restrict, tok::kw_return, tok::kw_short, tok::kw_signed, tok::kw_sizeof, \ + tok::kw_static, tok::kw_struct, tok::kw_switch, \ + tok::kw_typedef, tok::kw_union, tok::kw_unsigned, tok::kw_void, tok::kw_volatile, tok::kw_while)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "20.1:" << "C keyword undefined:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.1", "C keyword undefined : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C keyword undefined : "); + } + } + } + + if (DMD->getPrevious() != nullptr) + { + const MacroDirective* PMD = DMD->getPrevious(); + + if (PMD != nullptr) + { + SourceLocation PSL = PMD->getLocation(); + CheckSLValidity(PSL); + + if (SM.isInSystemHeader(PSL) || MI->isBuiltinMacro()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "20.1:" << "C standard library macro undefined:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.1", "C standard library macro undefined : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C standard library macro undefined : "); + } + } + } + } + } + /*end of 20.1*/ + + /*start of 19.5*/ + if (!MI->isBuiltinMacro() && SM.isInMainFile(SL) && !SM.isInSystemHeader(SL)) + { + MacroUndefSourceLocation.push_back(SL); + } + /*end of 19.5*/ + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.6:" << "Use of #undef is illegal:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.6", "Use of #undef is illegal : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.6", "Use of #undef is illegal : "); + } + } + } +#endif + } + + virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) + { +#if 1 + const MacroInfo* MI = MD->getMacroInfo(); + + SourceLocation SL = MacroNameTok.getLocation(); + CheckSLValidity(SL); + +#if 0 + assert(SL->isValid(), "the SourceLocation for MacroDefined is not valid."); +#endif + +#if __clang_major__ < 5 + unsigned MacroNumArgs = MI->getNumArgs(); +#elif __clang_major__ >= 5 + unsigned MacroNumArgs = MI->getNumParams(); +#endif + + /*start of 19.5*/ + if (!MI->isBuiltinMacro() && SM.isInMainFile(SL) && !SM.isInSystemHeader(SL)) + { + MacroDefSourceLocation.push_back(SM.getExpansionLoc(SL)); + MacroNameString.push_back(MacroNameTok.getIdentifierInfo()->getName().str()); + } + /*end of 19.5*/ + + /*start of 20.1*/ + /*inline and restrict are C99*/ + if (MacroNameTok.isOneOf(tok::kw_auto, tok::kw_break, tok::kw_case, tok::kw_char, tok::kw_const, tok::kw_continue, \ + tok::kw_default, tok::kw_do, tok::kw_double, tok::kw_else, tok::kw_enum, tok::kw_extern, \ + tok::kw_float, tok::kw_for, tok::kw_goto, tok::kw_if, tok::kw_inline, tok::kw_int, tok::kw_long, \ + tok::kw_register, tok::kw_restrict, tok::kw_return, tok::kw_short, tok::kw_signed, tok::kw_sizeof, \ + tok::kw_static, tok::kw_struct, tok::kw_switch, \ + tok::kw_typedef, tok::kw_union, tok::kw_unsigned, tok::kw_void, tok::kw_volatile, tok::kw_while)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "20.1:" << "C keyword defined:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.1", "C keyword defined : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C keyword defined : "); + } + } + } + + if (MD->getPrevious() != nullptr) + { + const MacroDirective* PMD = MD->getPrevious(); + SourceLocation PSL = PMD->getLocation(); + /*@DEVI-A quick fix.Fixme.*/ + CheckSLValidity(PSL); + + if (SM.isInSystemHeader(PSL) || MI->isBuiltinMacro()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "20.1:" << "C standard library macro redefined:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.1", "C standard library macro redefined : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C standard library macro redefined : "); + } + } + } + } + /*end of 20.1*/ + + ArrayRef TokenArrayRef = MI->tokens(); +#if __clang_major__ < 5 + ArrayRef MacroArgsArrRef = MI->args(); +#elif __clang_major__ >= 5 + ArrayRef MacroArgsArrRef = MI->params(); +#endif + + unsigned NumOfTokens = MI->getNumTokens(); + + bool hasSingleHash = false; + bool hasDoubleHash = false; + + for (unsigned x = 0; x < NumOfTokens; ++x) + { +#if 1 + if (TokenArrayRef[x].getKind() == tok::hash) + { + hasSingleHash = true; + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.13:" << "Macro has # token:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.13", "Macro has # token : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.13", "Macro has # token : "); + } + } + } + + if (TokenArrayRef[x].getKind() == tok::hashhash) + { + hasDoubleHash = true; + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.13:" << "Macro has ## token:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.13", "Macro has ## token : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.13", "Macro has ## token : "); + } + } + } +#endif + } + + if (hasSingleHash && hasDoubleHash) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.12:" << "Macro has # and ## tokens:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.12", "Macro has # and ## tokens : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.12", "Macro has # and ## tokens : "); + } + } + } + + if (MI->isFunctionLike()) + { + bool ShouldBeTagged = false; + bool IsIdentifierMacroArg = false; + bool HasHash = false; + + for (unsigned x = 0U; x < NumOfTokens; ++x) + { +#if 1 + /*@DEVI-for macro defs that dont have more than two token NumOfTokens will wrap around since its + unsigned if subtracted by two,hence the check. it does not hurt the logic since if there are less + than two token in a macro definition, then it cannot possibly have a hash or a double hash.*/ + if (NumOfTokens >= 2U) + { + if (TokenArrayRef[x].getKind() == tok::identifier) + { + for (unsigned xx = 0; xx < MacroNumArgs; ++xx) + { + if (TokenArrayRef[x].getIdentifierInfo()->getName().str() == MacroArgsArrRef[xx]->getName().str()) + { + IsIdentifierMacroArg = true; + } + } + + if (IsIdentifierMacroArg) + { + if (x <= NumOfTokens - 2U) + { + if (TokenArrayRef[x + 1U].getKind() == tok::hashhash) + { + HasHash = true; + } + } + + if (x >= 1U) + { + if (TokenArrayRef[x - 1U].getKind() == tok::hash || TokenArrayRef[x - 1U].getKind() == tok::hashhash) + { + HasHash = true; + } + } + + if (x <= NumOfTokens - 2U) + { + if (!(TokenArrayRef[x + 1U].getKind() == tok::r_paren) && !HasHash) + { + ShouldBeTagged = true; + } + } + + if (x >= 1U) + { + if (!(TokenArrayRef[x - 1U].getKind() == tok::l_paren) && !HasHash) + { + ShouldBeTagged = true; + } + } + } + } + + IsIdentifierMacroArg = false; + HasHash = false; + } +#endif + } + + if (ShouldBeTagged) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.10:" << "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.10", "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.10", "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash : "); + } + } + } + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.7:" << "Function-like macro used:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.7", "Function-like macro used : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.7", "Function-like macro used : "); + } + } + } + + if (MacroNumArgs != 0) + { + for (unsigned x = 0; x < MacroNumArgs; ++x) + { + if (MacroArgsArrRef[0]->hasMacroDefinition()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + std::cout << "19.9:" << "Function-like macro's argument contains macros:"; + std::cout << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.9", "Function-like macro's argument contains macros : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.9", "Function-like macro's argument contains macros : "); + } + } + + break; + } + } + } + } +#endif + } + + virtual void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) + { +#if 1 + SourceLocation SL = MacroNameTok.getLocation(); + CheckSLValidity(SL); + +#if 0 + assert(SL.isValid(), "the SourceLocation for MacroExpands is not valid."); +#endif + + IdentifierInfo* II = MacroNameTok.getIdentifierInfo(); + + std::string MacroNameString = II->getName().str(); + + DefMacroDirective* DMD = MD.getLocalDirective(); + + SourceLocation MDSL = DMD->getLocation(); + + MacroInfo* MI = MD.getMacroInfo(); + + /*start of 19.4*/ + ArrayRef TokenArrayRef = MI->tokens(); + + /*@DEVI-guard against macro defs that just define the macro without a value.*/ + if (TokenArrayRef.size() != 0U) + { + bool MacroExpansionIsTypeQualifier = true; + bool MacroExpansionIsStorageSpecifier = true; + bool MacroExpansionStringLiteral = false; + bool MacroExpansionConstant = false; + bool MacroExpansionBracedInitializer = true; + bool MacroExpansionParenExpr = true; + bool MacroExpansionDoWhileZero = true; + + if (TokenArrayRef.front().getKind() == tok::l_paren && TokenArrayRef.back().getKind() == tok::r_paren) + { + /*currently we do not care what's inside the parens.*/ + } + else + { + MacroExpansionParenExpr = false; + } + + if (TokenArrayRef.front().getKind() == tok::l_brace && TokenArrayRef.back().getKind() == tok::r_brace) + { + /*currently we don't care what's inside the curly braces.*/ + } + else + { + MacroExpansionBracedInitializer = false; + } + + //std::vector TokenPattern = {tok::kw_while, tok::l_paren, tok::numeric_constant, tok::r_paren}; + std::vector TokenPattern; + TokenPattern.push_back(tok::kw_while); + TokenPattern.push_back(tok::l_paren); + TokenPattern.push_back(tok::numeric_constant); + TokenPattern.push_back(tok::r_paren); + + if (TokenArrayRef.front().getKind() == tok::kw_do) + { + unsigned marker = 0U; + + for (ArrayRef::iterator iter = TokenArrayRef.begin(), iterE = TokenArrayRef.end(); iter != iterE; ++iter) + { + if (iter->getKind() == tok::kw_while) + { + marker = 0U; + } + + if (marker == 3U && iter->getKind() == TokenPattern[3]) + { + marker = 4U; + } + else if (marker == 3U && iter->getKind() != TokenPattern[3]) + { + marker = 0U; + } + else + { + /*empty*/ + } + + if (marker == 2U && iter->getKind() == TokenPattern[2]) + { + marker = 3U; + } + else if (marker == 2U && iter->getKind() != TokenPattern[2]) + { + marker = 0U; + } + else + { + /*empty*/ + } + + if (marker == 1U && iter->getKind() == TokenPattern[1]) + { + marker = 2U; + } + else if (marker == 1U && iter->getKind() != TokenPattern[1]) + { + + } + else + { + /*empty*/ + } + + if (marker == 0U && iter->getKind() == TokenPattern[0]) + { + marker = 1U; + } + } + + if (marker != 4U) + { + MacroExpansionDoWhileZero = false; + } + } + else + { + MacroExpansionDoWhileZero = false; + } + + if (TokenArrayRef.size() == 1U) + { + if (TokenArrayRef[0].getKind() == tok::string_literal || TokenArrayRef[0].getKind() == tok::wide_string_literal \ + || TokenArrayRef[0].getKind() == tok::utf8_string_literal || TokenArrayRef[0].getKind() == tok::utf16_string_literal \ + || TokenArrayRef[0].getKind() == tok::utf32_string_literal) + { + MacroExpansionStringLiteral = true; + } + + if (TokenArrayRef[0].getKind() == tok::numeric_constant || TokenArrayRef[0].getKind() == tok::char_constant \ + || TokenArrayRef[0].getKind() == tok::wide_char_constant || TokenArrayRef[0].getKind() == tok::utf8_char_constant \ + || TokenArrayRef[0].getKind() == tok::utf16_char_constant || TokenArrayRef[0].getKind() == tok::utf32_char_constant) + { + MacroExpansionConstant = true; + } + } + + for (auto &iter : TokenArrayRef) + { + if (iter.getKind() == tok::kw_const || iter.getKind() == tok::kw_restrict || iter.getKind() == tok::kw_volatile \ + || iter.getKind() == tok::l_paren || iter.getKind() == tok::r_paren) + { + /*has no significance*/ + } + else + { + MacroExpansionIsTypeQualifier = false; + } + + if (iter.getKind() == tok::kw_auto || iter.getKind() == tok::kw_extern || iter.getKind() == tok::kw_register \ + || iter.getKind() == tok::kw_static || iter.getKind() == tok::kw_typedef \ + || iter.getKind() == tok::l_paren || iter.getKind() == tok::r_paren) + { + /*has no significance*/ + } + else + { + MacroExpansionIsStorageSpecifier = false; + } + } + + if (!MacroExpansionIsTypeQualifier && !MacroExpansionIsStorageSpecifier \ + && !MacroExpansionStringLiteral && !MacroExpansionConstant \ + && !MacroExpansionBracedInitializer && !MacroExpansionParenExpr \ + && !MacroExpansionDoWhileZero) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) + { + std::cout << "19.4:" << "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier:"; + std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.4", "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.4", "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier : "); + } + } + } + } + /*end of 19.4*/ + +#if 1 + if (Args != nullptr) + { + /*@DEVI-Macro args are passed twice. first they are expanded and then the whole macro, + including the args is checked again for expansion, so args are passed twice.*/ +#if __clang_major__ == 4 + if (MI->getNumArgs() != Args->getNumArguments() - MI->getNumArgs()) +#elif __clang_major__ == 5 + if (MI->getNumParams() != Args->getNumMacroArguments() - MI->getNumParams()) +#elif __clang_major__ == 6 + if (MI->getNumParams() != Args->getNumMacroArguments() - MI->getNumParams()) +#endif + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) + { + std::cout << "19.8:" << "Funciton-like macro invoked with wrong number of arguments:"; +#if __clang_major__ == 4 + std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumArguments() << " " << MI->getNumArgs() << ":" << "\n"; +#elif __clang_major__ == 5 + std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumMacroArguments() << " " << MI->getNumParams() << ":" << "\n"; +#elif __clang_major__ == 6 + std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumMacroArguments() << " " << MI->getNumParams() << ":" << "\n"; +#endif + + XMLDocOut.XMLAddNode(SM, SL, "19.8", "Funciton-like macro invoked with wrong number of arguments:"); + JSONDocOUT.JSONAddElement(SM, SL, "19.8", "Funciton-like macro invoked with wrong number of arguments:"); + } + } + } + } +#endif + + if (MacroNameString == "offsetof") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) + { + std::cout << "20.6:" << "use of offsetof is illegal:"; + std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.6", "use of offsetof is illegal : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.6", "use of offsetof is illegal : "); + } + } + } + + if (MacroNameString == "setjmp") + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) + { + std::cout << "20.7:" << "use of setjmp is illegal:"; + std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "20.7", "use of setjmp is illegal : "); + JSONDocOUT.JSONAddElement(SM, SL, "20.7", "use of setjmp is illegal : "); + } + } + } + + if (!DMD->isDefined()) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) + { + /*intentionally left blank*/ + } + else + { + /*@DEVI-by the time we get a callback on our callback, the macri is assigned a default vlaue even if it is undefined in the TU.*/ + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) + { + std::cout << "19.11:" << "Use of undefined macro:"; + std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SL, "19.11", "Use of undefined macro : "); + JSONDocOUT.JSONAddElement(SM, SL, "19.11", "Use of undefined macro : "); + } + } + } +#endif + } + + virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc) + { +#if 1 + SourceLocation SLoc = SM.getSpellingLoc(Loc); + CheckSLValidity(SLoc); + SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); + CheckSLValidity(SIfLoc); + + if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) + { + std::cout << "19.17:" << "elif directive is not in the same file as its if directive:"; + std::cout << SLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "elif directive is not in the same file as its if directive : "); + JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "elif directive is not in the same file as its if directive : "); + } + } + } +#endif + } + + virtual void Else(SourceLocation Loc, SourceLocation IfLoc) + { +#if 1 + SourceLocation SLoc = SM.getSpellingLoc(Loc); + CheckSLValidity(SLoc); + SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); + CheckSLValidity(SIfLoc); + + if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) + { + std::cout << "19.17:" << "else directive is not in the same file as its if directive:"; + std::cout << SLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "else directive is not in the same file as its if directive : "); + JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "else directive is not in the same file as its if directive : "); + } + } + } +#endif + } + + virtual void Endif (SourceLocation Loc, SourceLocation IfLoc) + { +#if 1 + SourceLocation SLoc = SM.getSpellingLoc(Loc); + CheckSLValidity(SLoc); + SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); + CheckSLValidity(SIfLoc); + + if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) + { + std::cout << "19.17:" << "endif directive is not in the same file as its if directive:"; + std::cout << SLoc.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "endif directive is not in the same file as its if directive : "); + JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "endif directive is not in the same file as its if directive : "); + } + } + } +#endif + } + +private: + const SourceManager &SM; +}; +/**********************************************************************************************************************/ +class IsThereJunkPreInclusion +{ +public: + IsThereJunkPreInclusion() {} + + void Check(std::vector SourcePathList) + { + bool HaveWeMatchedInclusionDirYet = false; + bool HaveWeMatchIllegal191Yet = false; + + for (auto &iter : SourcePathList) + { + //std::cout << iter << "\n"; + std::ifstream InputFile(iter); + + HaveWeMatchIllegal191Yet = false; + HaveWeMatchedInclusionDirYet = false; + + for (std::string line; getline(InputFile, line);) + { + //std::cout << iter << ":" << line << ":" << HaveWeMatchedInclusionDirYet << " " << HaveWeMatchIllegal191Yet << "\n"; + + if (line.empty()) + { + continue; + } + + if (line.front() == '#') + { + size_t st = line.find("#include", 0U); + + if (st == 0U) + { + /*we've found a header include*/ + HaveWeMatchedInclusionDirYet = true; + + if (HaveWeMatchIllegal191Yet) + { + /*print diag out*/ + std::cout << "19.1" << ":" << "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments" << ":" << iter << "\n"; + + XMLDocOut.XMLAddNode(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); + JSONDocOUT.JSONAddElement(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); + break; + } + else + { + break; + } + } + + continue; + } + + if (line.front() == '/') + { + /*has to be a comment*/ + continue; + } + + if (line.front() == '\n' || line.front() == '\t' || line.front() == ' ' || line.front() == '\r') + { + HaveWeMatchIllegal191Yet = false; + + for (auto &iterchar : line) + { + if (iterchar == '\n' || iterchar == '\t' || iterchar == ' ' || line.front() == '\r') + { + continue; + } + + if (iterchar == '/') + { + break; + } + + if (iterchar == '#') + { + size_t st = line.find("#include", 0U); + + if (st == 0U) + { + /*we've found a header include*/ + HaveWeMatchedInclusionDirYet = true; + + if (HaveWeMatchIllegal191Yet) + { + /*print diag out*/ + std::cout << "19.1" << ":" << "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments" << ":" << iter << "\n"; + + XMLDocOut.XMLAddNode(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); + JSONDocOUT.JSONAddElement(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); + break; + } + else + { + break; + } + + + } + } + + HaveWeMatchIllegal191Yet = true; + } + + continue; + } + + HaveWeMatchIllegal191Yet = true; + } + + InputFile.close(); + } + } + +private: +}; +/**********************************************************************************************************************/ +class CheckForNullStatements +{ +public: + CheckForNullStatements() {} + + void Check(void) + { + bool HaveWeMatchedASemi = false; + bool ShouldBeTagged = false; + bool HaveWeSeenAComment = false; + bool WhiteSpacePostSemi = false; + + for (auto &iter : NullStmtProto) + { +#if 0 + std::cout << iter.Line << ":" << iter.Column << ":" << iter.FileName << "\n"; +#endif + + ShouldBeTagged = false; + HaveWeMatchedASemi = false; + HaveWeSeenAComment = false; + WhiteSpacePostSemi = false; + + std::ifstream InputFile(iter.FileName); + + unsigned counter = 0U; + + for (std::string line; getline(InputFile, line);) + { + counter++; + if (counter == iter.Line) + { + for (auto &iterchar : line) + { + if (iterchar == ';') + { + if (HaveWeMatchedASemi) + { + ShouldBeTagged = true; + break; + } + + HaveWeMatchedASemi = true; + continue; + } + + if (iterchar == ' ') + { + if (HaveWeMatchedASemi) + { + WhiteSpacePostSemi = true; + continue; + } + + if (WhiteSpacePostSemi) + { + ShouldBeTagged = true; + break; + } + + continue; + } + + if (iterchar == '\t') + { + + if (HaveWeMatchedASemi) + { + ShouldBeTagged = true; + break; + } + else + { + continue; + } + } + + if (iterchar == '/') + { + HaveWeSeenAComment = true; + + if (HaveWeMatchedASemi) + { + if (WhiteSpacePostSemi) + { + break; + } + else + { + ShouldBeTagged = true; + break; + } + } + else + { + ShouldBeTagged = true; + break; + } + + break; + } + + ShouldBeTagged = true; + break; + } + } + + if (ShouldBeTagged) + { + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, iter.IsInSysHeader)) + { + /*intentionally left blank*/ + } + else + { + if (Devi::IsTheMatchInMainFile(MainFileOnly, iter.IsInMainFile)) + { + std::cout << "14.3" << ":" << "Illegal NullStmt form:" << iter.FileName << ":" << iter.Line << ":" << iter.Column << ":" << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "14.3", "Illegal NullStmt form:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "14.3", "Illegal NullStmt form:"); + } + } + + break; + } + } + + InputFile.close(); + } + } + +private: +}; +/**********************************************************************************************************************/ +class onEndOfAllTUs +{ +public: onEndOfAllTUs() {} + + static void run(void) + { + /*@DEVI-start of 8.8*/ + for (auto &iter : ExternObjInfoProto) + { + if (iter.HasMoreThanOneDefinition) + { + std::cout << "8.8:" << "External function or object is defined in more than one file:"; + std::cout << iter.XObjSLStr << ":" << iter.XObjNameStr << "\n"; + + XMLDocOut.XMLAddNode(iter.LineNumber, iter.ColumnNumber, iter.FileName, "8.8", "External function or object is defined in more than one file: "); + JSONDocOUT.JSONAddElement(iter.LineNumber, iter.ColumnNumber, iter.FileName, "8.8", "External function or object is defined in more than one file: "); + } + } + /*end of 8.8*/ + + /*@DEVI-start of 5.x*/ + /*@DEVI-first we need to do some cleanup and mark some entries as invalid.*/ + for (auto &iter : IdentInfoProto) + { + if (iter.Name == "") + { + iter.IsValid = false; + } + + if (iter.NK == Devi::NodeKind::RecordDecl) + { + for (auto &yaiter : IdentInfoProto) + { + if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) + { + if ((iter.IsIncomplete != yaiter.IsIncomplete) && iter.IsValid && yaiter.IsValid) + { + iter.IsValid = false; + } + } + + if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) + { + yaiter.IsValid = false; + } + } + } + + if (iter.NK == Devi::NodeKind::FieldDecl) + { + for (auto &yaiter : IdentInfoProto) + { + if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) + { + yaiter.IsValid = false; + } + } + } + + if (iter.NK == Devi::NodeKind::ParmVarDecl) + { + for (auto &yaiter : IdentInfoProto) + { + if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) + { + yaiter.IsValid = false; + } + } + } + + if (iter.NK == Devi::NodeKind::FunctionDecl) + { + for (auto &yaiter : IdentInfoProto) + { + if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) + { + if (iter.FDKind != yaiter.FDKind && iter.IsValid && yaiter.IsValid) + { + iter.IsValid = false; + } + } + } + } + } + + /*@DEVI-now we can start looking for things to tag*/ + for (auto &iter : IdentInfoProto) + { + if (iter.IsValid == false) + { + continue; + } + + for (auto &yaiter : IdentInfoProto) + { + if (yaiter.IsValid == false) + { + continue; + } + + if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) + { + /*tag 5.7*/ + std::cout << "5.7:" << "Identifier re-used:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.7", "Identifier re-used:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.7", "Identifier re-used:"); + + if (iter.NK == Devi::NodeKind::TypedefDecl) + { + /*tag 5.3*/ + std::cout << "5.3:" << "Typedef identifier is not unique:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.3", "Typedef identifier is not unique:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.3", "Typedef identifier is not unique:"); + } + + if (iter.NK == Devi::NodeKind::RecordDecl) + { + /*tag 5.4*/ + std::cout << "5.4:" << "Tag identifier is not unique:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.4", "Tag identifier is not unique:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.4", "Tag identifier is not unique:"); + } + + if (iter.NK == Devi::NodeKind::RecordDecl && yaiter.NK != Devi::NodeKind::RecordDecl) + { + /*tag 5.6*/ + std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + } + + if (iter.NK == Devi::NodeKind::LabelDecl && yaiter.NK != Devi::NodeKind::LabelDecl) + { + /*tag 5.6*/ + std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + } + + if (((iter.NK != Devi::NodeKind::RecordDecl) && (iter.NK != Devi::NodeKind::LabelDecl)) && \ + ((yaiter.NK == Devi::NodeKind::RecordDecl) || (yaiter.NK == Devi::NodeKind::LabelDecl))) + { + /*tag 5.6*/ + std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); + } + + if (iter.FileName == yaiter.FileName && iter.Scope == Devi::Scope::Block && yaiter.Scope == Devi::Scope::TU) + { + /*tag 5.2*/ + std::cout << "5.2:" << "This identifier is being hidden by an identifier of the same name in file scope:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.2", "This identifier is being hidden by an identifier of the same name in file scope:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.2", "This identifier is being hidden by an identifier of the same name in file scope:"); + } + + if (iter.IsStatic) + { + /*tag 5.5*/ + std::cout << "5.5:" << "Identifier with static storage duration is re-used:"; + std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; + + XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.5", "Identifier with static storage duration is re-used:"); + JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.5", "Identifier with static storage duration is re-used:"); + } + } + } + } + /*end of 5.x*/ + } + +private: +}; +/**********************************************************************************************************************/ +class MyASTConsumer : public ASTConsumer { + +public: + MyASTConsumer(Rewriter &R) : HandlerForCmpless(R), HandlerWhileCmpless(R), HandlerElseCmpless(R), HandlerIfCmpless(R), \ + HandlerForIfElse(R), HandlerForSwitchBrkLess(R), HandlerForSwitchDftLEss(R), HandlerForMCSwitch151(R), HandlerForMCSwitch155(R), \ + HandlerForMCFunction161(R), HandlerForFunction162(R), HandlerForFunction164(R), HandlerForFunction166(R), HandlerForFunction168(R), \ + HandlerForFunction169(R), HandlerForPA171(R), HandlerForSU184(R), HandlerForType6465(R), HandlerForDCDF81(R), HandlerForDCDF82(R), \ + HandlerForInit91(R), HandlerForInit92(R), HandlerForInit93(R), HandlerForExpr123(R), HandlerForExpr124(R), HandlerForExpr125(R), \ + HandlerForExpr126(R), HandlerForExpr127(R), HandlerForExpr128(R), HandlerForExpr129(R), HandlerForExpr1210(R), HandlerForExpr1213(R), \ + HandlerForCSE131(R), HandlerForCSE132(R), HandlerForCSE1332(R), HandlerForCSE134(R), HandlerForCSE136(R), HandlerForCF144(R), \ + HandlerForCF145(R), HandlerForCF146(R), HandlerForCF147(R), HandlerForCF148(R), HandlerForSwitch154(R), HandlerForPTC111(R), \ + HandlerForCSE137(R), HandlerForDCDF810(R), HandlerForFunction165(R), HandlerForFunction1652(R), HandlerForPointer171(R), \ + HandlerForPointer1723(R), HandlerForPointer174(R), HandlerForPointer175(R), HandlerForTypes61(R), HandlerForSU181(R), \ + HandlerForMCPTCCSTYLE(R), HandlerForATC101(R), HandlerForIdent51(R), HandlerForDCDF87(R), HandlerForDCDF88(R), HandlerForLangX23(R), \ + HandlerForFunction167(R), HandlerForCF143(R), HandlerForExpr1212(R), HandlerForExpr1211(R), HandlerForAtc105(R), HandlerForCSE135(R), \ + HandlerForTypes612(R), HandlerForConst71(R), HandlerForIdent5X(R), HandlerForSFCPPARR01(R), HandlerForSFCPPARR02(R), \ + HandlerForSFCPPPNTR01(R), HandlerForSFCPPPNTR02(R) + { + +/*@DEVI-disables all matchers*/ +#if defined(_MUT0_EN_MATCHERS) + + Matcher.addMatcher(forStmt(unless(hasDescendant(compoundStmt()))).bind("mcfor"), &HandlerForCmpless); + + Matcher.addMatcher(whileStmt(unless(hasDescendant(compoundStmt()))).bind("mcwhile"), &HandlerWhileCmpless); + + Matcher.addMatcher(ifStmt(allOf(hasElse(unless(ifStmt())), hasElse(unless(compoundStmt())))).bind("mcelse"), &HandlerElseCmpless); + + Matcher.addMatcher(ifStmt(unless(hasDescendant(compoundStmt()))).bind("mcif"), &HandlerIfCmpless); + + Matcher.addMatcher(ifStmt(allOf(hasElse(ifStmt()), unless(hasAncestor(ifStmt())), unless(hasDescendant(ifStmt(hasElse(unless(ifStmt()))))))).bind("mcifelse"), &HandlerForIfElse); + + Matcher.addMatcher(switchStmt(hasDescendant(compoundStmt(hasDescendant(switchCase(unless(hasDescendant(breakStmt()))))))).bind("mcswitchbrk"), &HandlerForSwitchBrkLess); + + Matcher.addMatcher(switchStmt(unless(hasDescendant(defaultStmt()))).bind("mcswitchdft"), &HandlerForSwitchDftLEss); + + if (umRuleList.at("15.1")) + { + Matcher.addMatcher(switchStmt(forEachDescendant(caseStmt(hasAncestor(compoundStmt().bind("mccmp151"))).bind("mccase151"))), &HandlerForMCSwitch151); + } + + if (umRuleList.at("15.5")) + { + Matcher.addMatcher(switchStmt(unless(hasDescendant(caseStmt()))).bind("mcswitch155"), &HandlerForMCSwitch155); + } + + if (umRuleList.at("16.1")) + { + Matcher.addMatcher(functionDecl().bind("mcfunction161"), &HandlerForMCFunction161); + } + + if (umRuleList.at("16.2")) + { + Matcher.addMatcher(functionDecl(forEachDescendant(callExpr().bind("mc162callexpr"))).bind("mc162funcdec"), &HandlerForFunction162); + } + + if (umRuleList.at("16.4")) + { + Matcher.addMatcher(functionDecl().bind("mcfunc164"), &HandlerForFunction164); + } + + if (umRuleList.at("16.6")) + { + Matcher.addMatcher(callExpr().bind("mcfunc166"), &HandlerForFunction166); + } + + if (umRuleList.at("16.8")) + { + Matcher.addMatcher(functionDecl(forEachDescendant(returnStmt().bind("mcfunc168"))), &HandlerForFunction168); + } + + if (umRuleList.at("16.9")) + { + Matcher.addMatcher(implicitCastExpr(unless(hasAncestor(callExpr()))).bind("mcfunc169"), &HandlerForFunction169); + } + + if (umRuleList.at("17.1")) + { + Matcher.addMatcher(varDecl().bind("mcpa171"), &HandlerForPA171); + } + + if (umRuleList.at("18.4")) + { + Matcher.addMatcher(recordDecl(isUnion()).bind("mcsu184"), &HandlerForSU184); + } + + if (umRuleList.at("6.4") || umRuleList.at("6.5")) + { + Matcher.addMatcher(fieldDecl(isBitField()).bind("mctype6465"), &HandlerForType6465); + } + + if (umRuleList.at("8.1")) + { + Matcher.addMatcher(functionDecl().bind("mcdcdf81"), &HandlerForDCDF81); + } + + if (umRuleList.at("8.2")) + { + Matcher.addMatcher(varDecl().bind("mcdcdf82"), &HandlerForDCDF82); + } + + if (umRuleList.at("9.1")) + { + Matcher.addMatcher(varDecl().bind("mcinit91"), &HandlerForInit91); + } + + if (umRuleList.at("9.2")) + { + Matcher.addMatcher(initListExpr(hasAncestor(varDecl().bind("mcinit92daddy"))).bind("mcinit92"), &HandlerForInit92); + } + + if (umRuleList.at("9.3")) + { + Matcher.addMatcher(enumConstantDecl(anyOf(allOf(hasDescendant(integerLiteral().bind("mcinit93kiddy")), \ + hasAncestor(enumDecl().bind("mcinit93daddy"))), hasAncestor(enumDecl().bind("mcinit93daddy")))).bind("mcinit93"), &HandlerForInit93); + } + + if (umRuleList.at("12.3")) + { + Matcher.addMatcher(unaryExprOrTypeTraitExpr(hasDescendant(expr().bind("mcexpr123kiddy"))).bind("mcexpr123"), &HandlerForExpr123); + } + + if (umRuleList.at("12.4")) + { + Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), hasRHS(expr().bind("mcexpr124")))), &HandlerForExpr124); + } + + if (umRuleList.at("12.5")) + { + Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), \ + eachOf(hasRHS(allOf(expr().bind("lrhs"), unless(anyOf(implicitCastExpr() , declRefExpr(), callExpr(), floatLiteral(), integerLiteral(), stringLiteral()))))\ + , hasLHS(allOf(expr().bind("lrhs"), unless(anyOf(implicitCastExpr(), declRefExpr(), callExpr(), floatLiteral(), integerLiteral(), stringLiteral())))))))\ + , &HandlerForExpr125); + } + + if (umRuleList.at("12.6")) + { + Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), \ + eachOf(hasLHS(expr().bind("mcexpr126rl")), hasRHS(expr().bind("mcexpr126rl"))))), &HandlerForExpr126); + } + + if (umRuleList.at("12.7")) + { + Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("<<"), hasOperatorName(">>"), hasOperatorName("~"), hasOperatorName("<<="), \ + hasOperatorName(">>="), hasOperatorName("&"), hasOperatorName("&="), hasOperatorName("^"), hasOperatorName("^=")\ + , hasOperatorName("|"), hasOperatorName("|=")), eachOf(hasLHS(expr().bind("mcexpr127rl")), hasRHS(expr().bind("mcexpr127rl"))))), &HandlerForExpr127); + } + + if (umRuleList.at("12.8")) + { + Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName(">>"), hasOperatorName(">>="), hasOperatorName("<<="), hasOperatorName("<<")), \ + hasLHS(expr().bind("mcexpr128lhs")) , hasRHS(expr().bind("mcexpr128rhs")))), &HandlerForExpr128); + } + + if (umRuleList.at("12.9")) + { + Matcher.addMatcher(unaryOperator(allOf(hasOperatorName("-"), hasUnaryOperand(expr().bind("mcexpr129")))), &HandlerForExpr129); + } + + if (umRuleList.at("12.10")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(","), hasLHS(expr().bind("mcexpr1210")))), &HandlerForExpr1210); + } + + if (umRuleList.at("12.13")) + { + Matcher.addMatcher(unaryOperator(allOf(eachOf(hasOperatorName("++"), hasOperatorName("--"))\ + , anyOf(hasAncestor(binaryOperator()), hasDescendant(binaryOperator())))).bind("mcexpr1213"), &HandlerForExpr1213); + } + + if (umRuleList.at("13.1")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("="), eachOf(hasLHS(expr().bind("cse131rlhs")), hasRHS(expr().bind("cse131rlhs"))))), &HandlerForCSE131); + } + + if (umRuleList.at("13.2")) + { + Matcher.addMatcher(ifStmt(hasCondition(expr(unless(hasDescendant(binaryOperator(anyOf(hasOperatorName("<")\ + , hasOperatorName(">"), hasOperatorName("=="), hasOperatorName("<="), hasOperatorName(">=")))))).bind("mccse132"))), &HandlerForCSE132); + } + + if (umRuleList.at("13.3")) + { + Matcher.addMatcher(binaryOperator(allOf(anyOf(hasOperatorName("<"), hasOperatorName(">"), hasOperatorName("<="), hasOperatorName(">="), hasOperatorName("==")), \ + eachOf(hasLHS(expr().bind("mccse1332rl")), hasRHS(expr().bind("mccse1332rl"))))).bind("mccse1332daddy"), &HandlerForCSE1332); + } + + if (umRuleList.at("13.4")) + { + Matcher.addMatcher(forStmt().bind("mccse134"), &HandlerForCSE134); + } + + if (umRuleList.at("13.6")) + { + Matcher.addMatcher(forStmt(forEachDescendant(stmt(eachOf(unaryOperator(allOf(anyOf(hasOperatorName("++"), hasOperatorName("--")), hasUnaryOperand(declRefExpr().bind("mccse136kiddo")))), \ + binaryOperator(allOf(hasOperatorName("="), hasLHS(declRefExpr().bind("mccse136kiddo")))))))).bind("mccse136daddy"), &HandlerForCSE136); + } + + if (umRuleList.at("14.4")) + { + Matcher.addMatcher(gotoStmt().bind("mccf144"), &HandlerForCF144); + } + + if (umRuleList.at("14.5")) + { + Matcher.addMatcher(continueStmt().bind("mccf145"), &HandlerForCF145); + } + + if (umRuleList.at("14.6")) + { + Matcher.addMatcher(breakStmt(hasAncestor(stmt(anyOf(forStmt().bind("mccffofo"), doStmt().bind("mccfdodo"), whileStmt().bind("mccfwuwu"))))), &HandlerForCF146); + } + + if (umRuleList.at("14.7")) + { + Matcher.addMatcher(returnStmt(hasAncestor(functionDecl().bind("mccf147"))), &HandlerForCF147); + } + + if (umRuleList.at("14.8")) + { + Matcher.addMatcher(forStmt(unless(has(compoundStmt()))).bind("mccf148for"), &HandlerForCF148); + } + + if (umRuleList.at("14.8")) + { + Matcher.addMatcher(whileStmt(unless(has(compoundStmt()))).bind("mccf148while"), &HandlerForCF148); + } + + if (umRuleList.at("14.8")) + { + Matcher.addMatcher(doStmt(unless(has(compoundStmt()))).bind("mccf148do"), &HandlerForCF148); + } + + if (umRuleList.at("14.8")) + { + Matcher.addMatcher(switchStmt(unless(has(compoundStmt()))).bind("mccf148switch"), &HandlerForCF148); + } + + if (umRuleList.at("15.4")) + { + Matcher.addMatcher(switchStmt(hasCondition(expr().bind("mcswitch154"))).bind("mcswitch154daddy"), &HandlerForSwitch154); + } + + if (umRuleList.at("11.1")) + { + Matcher.addMatcher(implicitCastExpr().bind("mcptc111"), &HandlerForPTC111); + } + + if (umRuleList.at("13.7")) + { + Matcher.addMatcher(expr().bind("mccse137"), &HandlerForCSE137); + } + + if (umRuleList.at("8.10")) + { + Matcher.addMatcher(callExpr(hasAncestor(functionDecl().bind("mcdcdf810daddy"))).bind("mcdcdf810"), &HandlerForDCDF810); + } + + if (umRuleList.at("16.5")) + { + Matcher.addMatcher(functionDecl(allOf(returns(anything()), unless(returns(asString("void"))), hasBody(compoundStmt()) \ + , unless(hasDescendant(returnStmt())))).bind("mcfunction165"), &HandlerForFunction165); + } + + if (umRuleList.at("16.5")) + { + Matcher.addMatcher(functionDecl(allOf(parameterCountIs(0), hasBody(compoundStmt()))).bind("mcfunction1652"), &HandlerForFunction1652); + } + + if (umRuleList.at("17.1")) + { + Matcher.addMatcher(declRefExpr(allOf(to(varDecl().bind("loco")), unless(hasParent(castExpr(hasCastKind(clang::CK_ArrayToPointerDecay)))), \ + hasAncestor(stmt(eachOf(binaryOperator(hasOperatorName("+")).bind("bino"), \ + binaryOperator(hasOperatorName("-")).bind("bino"), unaryOperator(hasOperatorName("++")).bind("uno"), \ + unaryOperator(hasOperatorName("--")).bind("uno"), binaryOperator(hasOperatorName("/")).bind("bino"), \ + binaryOperator(hasOperatorName("*")).bind("bino"), binaryOperator(hasOperatorName("<")).bind("bino"), \ + binaryOperator(hasOperatorName("<=")).bind("bino"), binaryOperator(hasOperatorName(">")).bind("bino"), \ + binaryOperator(hasOperatorName(">=")).bind("bino")))))).bind("mcpointer171"), &HandlerForPointer171); + } + + /*start of 17.3 matchers*/ + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("<="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("<"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(">="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(">"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("-"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + + if (umRuleList.at("17.2") || umRuleList.at("17.3")) + { + Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("-="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ + hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ + has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); + } + /*end of 17.3 matchers*/ + + /*start of 17.4 matchers*/ + if (umRuleList.at("17.4")) + { + Matcher.addMatcher(castExpr(allOf(hasCastKind(CK_ArrayToPointerDecay), unless(hasParent(arraySubscriptExpr())))).bind("mcpointer174"), &HandlerForPointer174); + } + + if (umRuleList.at("17.4")) + { + Matcher.addMatcher(declRefExpr(allOf(hasAncestor(expr(anyOf(binaryOperator(hasOperatorName("-=")), \ + unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), \ + binaryOperator(hasOperatorName("+")), binaryOperator(hasOperatorName("+=")), \ + binaryOperator(hasOperatorName("-"))))), to(varDecl(hasType(pointerType()))))).bind("mcpointer1742"), &HandlerForPointer174); + } + /*end of 17.4 matchers*/ + + if (umRuleList.at("17.5")) + { + Matcher.addMatcher(varDecl(hasType(pointerType())).bind("mcpointer175"), &HandlerForPointer175); + } + + if (umRuleList.at("17.5")) + { + Matcher.addMatcher(fieldDecl().bind("mcpointer175field"), &HandlerForPointer175); + } + + if (umRuleList.at("6.1")) + { + Matcher.addMatcher(declRefExpr(allOf(to(varDecl().bind("mctypes6origin")), \ + hasAncestor(binaryOperator(allOf(hasRHS(expr().bind("mctypes6rhs")), \ + hasOperatorName("="))).bind("mctypes6dous")), hasType(isAnyCharacter()))), &HandlerForTypes61); + } + + if (umRuleList.at("18.1")) + { + Matcher.addMatcher(varDecl(hasType(incompleteArrayType())).bind("mcsu181arr"), &HandlerForSU181); + } + + if (umRuleList.at("18.1")) + { + Matcher.addMatcher(recordDecl(isStruct()).bind("mcsu181struct"), &HandlerForSU184); + } + + Matcher.addMatcher(cStyleCastExpr().bind("mcptc11cstyle"), &HandlerForMCPTCCSTYLE); + + if (umRuleList.at("10.1")) + { + Matcher.addMatcher(implicitCastExpr(has(expr(anyOf(binaryOperator().bind("atcdous"), unaryOperator().bind("atcuno"), \ + parenExpr().bind("atcparens"), implicitCastExpr().bind("atckidice"), \ + cStyleCastExpr().bind("atccstyle"))))).bind("atcdaddy"), &HandlerForATC101); + } + + if (umRuleList.at("5.1")) + { + Matcher.addMatcher(namedDecl().bind("ident5nameddecl"), &HandlerForIdent51); + } + + if (umRuleList.at("8.7")) + { + Matcher.addMatcher(declRefExpr(allOf(hasAncestor(functionDecl().bind("mcdcdf87daddy")), \ + to(varDecl(unless(hasAncestor(functionDecl()))).bind("mcdcdf87origin")))).bind("mcdcdfobj"), &HandlerForDCDF87); + } + +/*@DEVI-these two matcheres are breaking our 3.9 backwards compatibility.*/ +#if 1 + if (umRuleList.at("8.8")) + { + Matcher.addMatcher(functionDecl(hasExternalFormalLinkage()).bind("mcdcdf88function"), &HandlerForDCDF88); + } + + if (umRuleList.at("8.8")) + { + Matcher.addMatcher(varDecl(hasExternalFormalLinkage()).bind("mcdcdf88var"), &HandlerForDCDF88); + } +#endif + + if (umRuleList.at("2.3")) + { + Matcher.addMatcher(expr().bind("mclangx23"), &HandlerForLangX23); + } + + if (umRuleList.at("16.7")) + { + Matcher.addMatcher(parmVarDecl(unless(allOf(hasAncestor(functionDecl(hasDescendant(binaryOperator(allOf(hasOperatorName("="), \ + hasLHS(hasDescendant(declRefExpr(allOf(hasAncestor(unaryOperator(hasOperatorName("*"))), \ + to(parmVarDecl(hasType(pointerType())).bind("zulu"))))))))))), equalsBoundNode("zulu")))).bind("mcfunction167"), &HandlerForFunction167); + } + + if (umRuleList.at("14.3")) + { + Matcher.addMatcher(nullStmt().bind("mccf143nullstmt"), &HandlerForCF143); + } + + if (umRuleList.at("12.12")) + { + Matcher.addMatcher(recordDecl(allOf(has(fieldDecl(hasType(realFloatingPointType()))), isUnion())).bind("mcexpr1212"), &HandlerForExpr1212); + } + + if (umRuleList.at("12.11")) + { + Matcher.addMatcher(expr(hasDescendant(expr(anyOf(unaryOperator(hasOperatorName("--"), hasOperatorName("++")).bind("mcexpr1211uno"), \ + binaryOperator(anyOf(hasOperatorName("*"), hasOperatorName("/"), \ + hasOperatorName("-"), hasOperatorName("+"))).bind("mcexpr1211dous"))))).bind("mcexpr1211"), &HandlerForExpr1211); + } + + if (umRuleList.at("10.5")) + { + Matcher.addMatcher(binaryOperator(allOf(hasLHS(expr(hasType(isInteger())).bind("mcatc105lhs")), hasOperatorName("<<"))).bind("mcatc105"), &HandlerForAtc105); + } + + if (umRuleList.at("10.5")) + { + Matcher.addMatcher(unaryOperator(allOf(hasOperatorName("~") , hasUnaryOperand(expr(hasType(isInteger())).bind("mcatc105lhs")))).bind("mcatc105uno"), &HandlerForAtc105); + } + + if (umRuleList.at("13.5")) + { + Matcher.addMatcher(forStmt().bind("mccse135"), &HandlerForCSE135); + } + + if (umRuleList.at("6.1") || umRuleList.at("6.2")) + { + Matcher.addMatcher(binaryOperator(allOf(hasRHS(expr(has(expr(anyOf(integerLiteral().bind("mc612intlit"), \ + characterLiteral().bind("mc612charlit")))))), hasLHS(expr(hasType(isAnyCharacter())).bind("mc612exp")), \ + hasOperatorName("="))), &HandlerForTypes612); + } + + /*@DEVI-start of 7.1 matchers.*/ + if (umRuleList.at("7.1")) + { + Matcher.addMatcher(stringLiteral().bind("mcconst71string"), &HandlerForConst71); + } + + if (umRuleList.at("7.1")) + { + Matcher.addMatcher(characterLiteral().bind("mcconst71char"), &HandlerForConst71); + } + + if (umRuleList.at("7.1")) + { + Matcher.addMatcher(integerLiteral().bind("mcconst71int"), &HandlerForConst71); + } + /*end of 7.1*/ + + /*@DEVI-matchers for 5.x*/ + /*@DEVI-typedefs always have file scope.*/ + if (umRuleList.at("5.1") || umRuleList.at("5.2"), umRuleList.at("5.3") || umRuleList.at("5.4") || umRuleList.at("5.5") || umRuleList.at("5.6") || umRuleList.at("5.7")) + { + Matcher.addMatcher(typedefDecl().bind("ident5typedef"), &HandlerForIdent5X); + } + +#if 0 + Matcher.addMatcher(typedefDecl(unless(hasAncestor(functionDecl()))).bind("ident5typedef"), &HandlerForIdent5X); + + Matcher.addMatcher(typedefDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5typedef"), &HandlerForIdent5X); +#endif + + + if (umRuleList.at("5.1") || umRuleList.at("5.2"), umRuleList.at("5.3") || umRuleList.at("5.4") || umRuleList.at("5.5") || umRuleList.at("5.6") || umRuleList.at("5.7")) + { + Matcher.addMatcher(recordDecl(unless(hasAncestor(functionDecl()))).bind("ident5record"), &HandlerForIdent5X); + + Matcher.addMatcher(recordDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5record"), &HandlerForIdent5X); + + Matcher.addMatcher(fieldDecl(unless(hasAncestor(functionDecl()))).bind("ident5field"), &HandlerForIdent5X); + + Matcher.addMatcher(fieldDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5field"), &HandlerForIdent5X); + + Matcher.addMatcher(parmVarDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5parmvar"), &HandlerForIdent5X); + + Matcher.addMatcher(functionDecl().bind("ident5func"), &HandlerForIdent5X); + + Matcher.addMatcher(varDecl(unless(hasAncestor(functionDecl()))).bind("ident5var"), &HandlerForIdent5X); + + Matcher.addMatcher(varDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5var"), &HandlerForIdent5X); + + Matcher.addMatcher(enumDecl(unless(hasAncestor(functionDecl()))).bind("ident5enum") , &HandlerForIdent5X); + + Matcher.addMatcher(enumDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5enum"), &HandlerForIdent5X); + + /*@DEVI-labels always have function scope.*/ + Matcher.addMatcher(labelDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5label"), &HandlerForIdent5X); + + Matcher.addMatcher(enumConstantDecl(unless(hasAncestor(functionDecl()))).bind("ident5enumconst"), &HandlerForIdent5X); + + Matcher.addMatcher(enumConstantDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5enumconst"), &HandlerForIdent5X); + } + /*end of matchers for 5.x*/ + + /*start of SaferCPP matchers*/ + Matcher.addMatcher(varDecl(hasType(arrayType())).bind("sfcpparrdecl"), &HandlerForSFCPPARR01); + + Matcher.addMatcher(fieldDecl(hasType(arrayType())).bind("sfcpparrfield"), &HandlerForSFCPPARR01); + + Matcher.addMatcher(implicitCastExpr(hasCastKind(CK_ArrayToPointerDecay)).bind("sfcpparrcastexpr"), &HandlerForSFCPPARR01); + + Matcher.addMatcher(cStyleCastExpr(hasCastKind(CK_ArrayToPointerDecay)).bind("sfcpparrcastexpr"), &HandlerForSFCPPARR01); + + Matcher.addMatcher(declRefExpr(hasAncestor(binaryOperator(allOf(hasLHS(declRefExpr().bind("sfcpparrdeep")), hasRHS(hasDescendant(implicitCastExpr(hasCastKind(CK_ArrayToPointerDecay))))\ + , hasOperatorName("="))))), &HandlerForSFCPPARR02); + + Matcher.addMatcher(varDecl(hasType(pointerType())).bind("sfcpppntr01"), &HandlerForSFCPPPNTR01); + + Matcher.addMatcher(declRefExpr(hasType(pointerType())).bind("sfcpppntr02"), &HandlerForSFCPPPNTR02); + /*end of SaferCPP matchers*/ + +#endif + } + + void HandleTranslationUnit(ASTContext &Context) override { + Matcher.matchAST(Context); + } + +private: + MCForCmpless HandlerForCmpless; + MCWhileCmpless HandlerWhileCmpless; + MCElseCmpless HandlerElseCmpless; + MCIfCmpless HandlerIfCmpless; + IfElseMissingFixer HandlerForIfElse; + MCSwitchBrkless HandlerForSwitchBrkLess; + MCSwitchDftLess HandlerForSwitchDftLEss; + MCSwitch151 HandlerForMCSwitch151; + MCSwitch155 HandlerForMCSwitch155; + MCFunction161 HandlerForMCFunction161; + MCFunction162 HandlerForFunction162; + MCFunction164 HandlerForFunction164; + MCFunction166 HandlerForFunction166; + MCFunction168 HandlerForFunction168; + MCFunction169 HandlerForFunction169; + MCPA171 HandlerForPA171; + MCSU184 HandlerForSU184; + MCTypes6465 HandlerForType6465; + MCDCDF81 HandlerForDCDF81; + MCDCDF82 HandlerForDCDF82; + MCInit91 HandlerForInit91; + MCInit92 HandlerForInit92; + MCInit93 HandlerForInit93; + MCExpr123 HandlerForExpr123; + MCExpr124 HandlerForExpr124; + MCExpr125 HandlerForExpr125; + MCExpr126 HandlerForExpr126; + MCExpr127 HandlerForExpr127; + MCExpr128 HandlerForExpr128; + MCExpr129 HandlerForExpr129; + MCExpr1210 HandlerForExpr1210; + MCExpr1213 HandlerForExpr1213; + MCCSE131 HandlerForCSE131; + MCCSE132 HandlerForCSE132; + MCCSE1332 HandlerForCSE1332; + MCCSE134 HandlerForCSE134; + MCCSE136 HandlerForCSE136; + MCCF144 HandlerForCF144; + MCCF145 HandlerForCF145; + MCCF146 HandlerForCF146; + MCCF147 HandlerForCF147; + MCCF148 HandlerForCF148; + MCSwitch154 HandlerForSwitch154; + MCPTC111 HandlerForPTC111; + MCCSE137 HandlerForCSE137; + MCDCDF810 HandlerForDCDF810; + MCFunction165 HandlerForFunction165; + MCFunction1652 HandlerForFunction1652; + MCPointer171 HandlerForPointer171; + MCPointer1723 HandlerForPointer1723; + MCPointer174 HandlerForPointer174; + MCPointer175 HandlerForPointer175; + MCTypes61 HandlerForTypes61; + MCSU181 HandlerForSU181; + MCPTC11CSTYLE HandlerForMCPTCCSTYLE; + MCATC101 HandlerForATC101; + MCIdent51 HandlerForIdent51; + MCDCDF87 HandlerForDCDF87; + MCDCDF88 HandlerForDCDF88; + MCLangX23 HandlerForLangX23; + MCFunction167 HandlerForFunction167; + MCCF143 HandlerForCF143; + MCExpr1212 HandlerForExpr1212; + MCExpr1211 HandlerForExpr1211; + MCATC105 HandlerForAtc105; + MCCSE135 HandlerForCSE135; + MCTypes612 HandlerForTypes612; + MCConst71 HandlerForConst71; + MCIdent5x HandlerForIdent5X; + SFCPPARR01 HandlerForSFCPPARR01; + SFCPPARR02 HandlerForSFCPPARR02; + SFCPPPNTR01 HandlerForSFCPPPNTR01; + SFCPPPNTR02 HandlerForSFCPPPNTR02; + MatchFinder Matcher; +}; +/**********************************************************************************************************************/ +class Mutator0DiagnosticConsumer : public clang::DiagnosticConsumer +{ +public: + + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override + { + DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); + + SourceLocation SL = Info.getLocation(); + CheckSLValidity(SL); + + SourceManager &SM = Info.getSourceManager(); + + if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) + { + return void(); + } + + if (!Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) + { + return void(); + } + + SL = SM.getSpellingLoc(SL); + + unsigned SpellingLine = SM.getSpellingLineNumber(SL); + unsigned SpellingColumn = SM.getSpellingColumnNumber(SL); + std::string FileName = SM.getFilename(SL).str(); + + SmallString<100> DiagBuffer; + + Info.FormatDiagnostic(DiagBuffer); + +#if 0 + std::cout << "ClangDiag:" << DiagBuffer.str().str() << ":" << SL.printToString(SM) << ":" << Info.getID() << ":" << "\n"; +#endif + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "ClangDiag", DiagBuffer.str().str()); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "ClangDiag", DiagBuffer.str().str()); + + if (Info.getID() == 872U) + { + std::cout << "2.2:" << "Illegal comment format(/*...*/) used:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "2.2", "Illegal comment format(/*...*/) used:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "2.2", "Illegal comment format(/*...*/) used:"); + } + + if (Info.getID() == 974U) + { + std::cout << "2.3:" << "Use of the character sequence /* inside a comment is illegal:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "2.3", "Use of the character sequence /* inside a comment is illegal:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "2.3", "Use of the character sequence /* inside a comment is illegal:"); + } + + if (Info.getID() == 938U) + { + std::cout << "4.2:" << "Use of trigraphs is illegal:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "4.2", "Use of trigraphs is illegal:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "4.2", "Use of trigraphs is illegal:"); + } + + if (Info.getID() == 4578U) + { + std::cout << "9.2:" << "Brace initialization has either not been correctly used or not used at all:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "9.2", "Brace initialization has either not been correctly used or not used at all:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "9.2", "Brace initialization has either not been correctly used or not used at all:"); + } + + if (Info.getID() == 4872U) + { + std::cout << "14.2:" << "Expression result is unused:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "14.2", "Expression result is unused:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "14.2", "Expression result is unused:"); + } + + if (Info.getID() == 966U) + { + std::cout << "19.14:" << "\"defined\" has undefined behaviour:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "19.14", "\"defined\" has undefined behaviour:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "19.14", "\"defined\" has undefined behaviour:"); + } + + if (Info.getID() == 895U) + { + std::cout << "20.1:" << "Redefining built-in macro:" << SL.printToString(SM) << ":" << "\n"; + + XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "20.1", "Redefining built-in macro:"); + JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "20.1", "Redefining built-in macro:"); + } + + } + +private: + +}; +/**********************************************************************************************************************/ +class MyFrontendAction : public ASTFrontendAction +{ +public: + MyFrontendAction() {} + + void EndSourceFileAction() override + { + + } + + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override + { +#if 1 + CI.getPreprocessor().addPPCallbacks(llvm::make_unique(&CI.getSourceManager())); +#endif + + DiagnosticsEngine &DiagEngine = CI.getPreprocessor().getDiagnostics(); + +#if 1 + Mutator0DiagnosticConsumer* M0DiagConsumer = new Mutator0DiagnosticConsumer; + + DiagEngine.setClient(M0DiagConsumer, true); +#endif + + TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); + return llvm::make_unique(TheRewriter); + } + +private: + Rewriter TheRewriter; +}; +/**********************************************************************************************************************/ +/*Main*/ +int main(int argc, const char **argv) +{ + CommonOptionsParser op(argc, argv, MutatorLVL0Cat); + + CompilationDatabase &CDB [[maybe_unused]] = op.getCompilations(); + std::vector ComCom = CDB.getAllCompileCommands(); + std::vector> ExecCL; + +#if defined(_MUT0_TEST) + for (auto &iter : ComCom) + { + ExecCL.push_back(iter.CommandLine); + } + + for (auto &iter : ExecCL) + { + for (auto &yaiter : iter) + { + std::cout << "comcom: " << yaiter << "\n"; + } + + std::cout << "\n"; + } +#endif + + const std::vector &SourcePathList = op.getSourcePathList(); + + ClangTool Tool(op.getCompilations(), op.getSourcePathList()); + + StringOptionsParser SOPProto; + + SOPProto.MC2Parser(); + +#if defined(_MUT0_TEST) + SOPProto.Dump(true); +#endif + +#if defined(_MUT0_TEST) + if (SOPProto.MC2Parser()) + { + typedef std::multimap::iterator Iter; + for (Iter iter = MC1EquivalencyMap.begin(), iterE = MC1EquivalencyMap.end(); iter != iterE; ++iter) + { + std::cout << "Key: " << iter->first << " " << "Value: " << iter->second << "\n"; + } + } +#endif + + XMLDocOut.XMLCreateReport(); + + JSONDocOUT.JSONCreateReport(); + + IsThereJunkPreInclusion ITJPIInstance; + + ITJPIInstance.Check(SourcePathList); + + int RunResult = 0; + + try + { + RunResult = Tool.run(newFrontendActionFactory().get()); + } + catch (MutExHeaderNotFound &E1) + { + std::cerr << E1.what() << "\n"; + } + catch (std::domain_error &E2) + { + std::cerr << E2.what() << "\n"; + } + catch(...) + { + std::cerr << "Unexpected exception!\n"; + } + + CheckForNullStatements CheckForNull; + + CheckForNull.Check(); + + onEndOfAllTUs::run(); + + XMLDocOut.SaveReport(); + + JSONDocOUT.CloseReport(); + + ME.DumpAll(); + ME.XMLReportAncestry(); + + return RunResult; +} //end of main +/*last line intentionally left blank.*/ + diff --git a/m0/mutator-lvl0.h b/m0/mutator-lvl0.h new file mode 100644 index 0000000..c1e452a --- /dev/null +++ b/m0/mutator-lvl0.h @@ -0,0 +1,542 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ +/**********************************************************************************************************************/ +/*inclusion guard*/ +#ifndef MUTATOR_0_H +#define MUTATOR_0_H +/**********************************************************************************************************************/ +/*included modules*/ +/*project headers*/ +#include "mutator_report.h" +/*standard library headers*/ +#include +#include +#include +#include +#include +#include +/*clang headers*/ +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTTypeTraits.h" +/**********************************************************************************************************************/ +/*externals*/ +/**********************************************************************************************************************/ +struct WeakPoint +{ + WeakPoint(std::string __psft, std::string __file, unsigned int __ln, unsigned int __cn) + { + PlaceHolderStringForType = __psft; + File = __file; + LineNumber = __ln; + ColumnNumber = __cn; + } + + std::string PlaceHolderStringForType; + std::string File; + unsigned int LineNumber; + unsigned int ColumnNumber; +}; +/**********************************************************************************************************************/ +std::map MC2OptsMap = { + {"1.1", false}, + {"1.2", false}, + {"1.3", false}, + {"1.4", false}, + {"1.5", false}, + {"2.1", false}, + {"2.2", false}, + {"2.3", false}, + {"2.4", false}, + {"3.1", false}, + {"3.2", false}, + {"3.3", false}, + {"3.4", false}, + {"3.5", false}, + {"3.6", false}, + {"4.1", false}, + {"4.2", false}, + {"5.1", false}, + {"5.2", false}, + {"5.3", false}, + {"5.4", false}, + {"5.5", false}, + {"5.6", false}, + {"5.7", false}, + {"6.1", false}, + {"6.2", false}, + {"6.3", false}, + {"6.4", false}, + {"6.5", false}, + {"7.1", false}, + {"8.1", false}, + {"8.2", false}, + {"8.3", false}, + {"8.4", false}, + {"8.5", false}, + {"8.6", false}, + {"8.7", false}, + {"8.8", false}, + {"8.9", false}, + {"8.10", false}, + {"8.11", false}, + {"8.12", false}, + {"9.1", false}, + {"9.2", false}, + {"9.3", false}, + {"10.1", false}, + {"10.2", false}, + {"10.3", false}, + {"10.4", false}, + {"10.5", false}, + {"10.6", false}, + {"11.1", false}, + {"11.2", false}, + {"11.3", false}, + {"11.4", false}, + {"11.5", false}, + {"12.1", false}, + {"12.2", false}, + {"12.3", false}, + {"12.4", false}, + {"12.5", false}, + {"12.6", false}, + {"12.7", false}, + {"12.8", false}, + {"12.9", false}, + {"12.10", false}, + {"12.11", false}, + {"12.12", false}, + {"12.13", false}, + {"13.1", false}, + {"13.2", false}, + {"13.3", false}, + {"13.4", false}, + {"13.5", false}, + {"13.6", false}, + {"13.7", false}, + {"14.1", false}, + {"14.2", false}, + {"14.3", false}, + {"14.4", false}, + {"14.5", false}, + {"14.6", false}, + {"14.7", false}, + {"14.8", false}, + {"14.9", false}, + {"14.10", false}, + {"15.0", false}, + {"15.1", false}, + {"15.2", false}, + {"15.3", false}, + {"15.4", false}, + {"15.5", false}, + {"16.1", false}, + {"16.2", false}, + {"16.3", false}, + {"16.4", false}, + {"16.5", false}, + {"16.6", false}, + {"16.7", false}, + {"16.8", false}, + {"16.9", false}, + {"16.10", false}, + {"17.1", false}, + {"17.2", false}, + {"17.3", false}, + {"17.4", false}, + {"17.5", false}, + {"17.6", false}, + {"18.1", false}, + {"18.2", false}, + {"18.3", false}, + {"18.4", false}, + {"19.1", false}, + {"19.2", false}, + {"19.3", false}, + {"19.4", false}, + {"19.5", false}, + {"19.6", false}, + {"19.7", false}, + {"19.8", false}, + {"19.9", false}, + {"19.10", false}, + {"19.11", false}, + {"19.12", false}, + {"19.13", false}, + {"19.14", false}, + {"19.15", false}, + {"19.16", false}, + {"19.17", false}, + {"20.1", false}, + {"20.2", false}, + {"20.3", false}, + {"20.4", false}, + {"20.5", false}, + {"20.6", false}, + {"20.7", false}, + {"20.8", false}, + {"20.9", false}, + {"20.10", false}, + {"20.11", false}, + {"20.12", false}, + {"21.1", false} +}; + +std::multimap MC1EquivalencyMap = { + {"1","1.1"}, + {"1","1.2"}, + {"1","2.2"}, + {"1","3.1"}, + {"2","1.3"}, + {"3","2.1"}, + {"4","21.1"}, + {"5","4.1"}, + {"6","3.2"}, + {"7","4.2"}, + {"8","rsc"}, + {"9","2.3"}, + {"10","2.4"}, + {"11","1.4"}, + {"12","5.5"}, + {"12","5.6"}, + {"12","5.7"}, + {"13","6.3"}, + {"14","6.1"}, + {"14","6.2"}, + {"15","1.5"}, + {"16","12.12"}, + {"17","5.3"}, + {"18","rsc"}, + {"19","7.1"}, + {"20","rsc"}, + {"21","5.2"}, + {"22","8.7"}, + {"23","8.10"}, + {"24","8.11"}, + {"25","8.9"}, + {"26","8.4"}, + {"27","8.8"}, + {"28","rsc"}, + {"29","5.4"}, + {"30","9.1"}, + {"31","9.2"}, + {"32","9.3"}, + {"33","12.4"}, + {"34","12.5"}, + {"35","13.1"}, + {"36","12.6"}, + {"37","10.5"}, + {"37","12.7"}, + {"38","12.8"}, + {"39","12.9"}, + {"40","12.3"}, + {"41","3.3"}, + {"42","12.10"}, + {"43","10.1"}, + {"44","rsc"}, + {"45","11.1"}, + {"45","11.2"}, + {"45","11.3"}, + {"45","11.4"}, + {"45","11.5"}, + {"46","12.2"}, + {"47","12.1"}, + {"48","10.4"}, + {"49","13.2"}, + {"50","13.3"}, + {"51","12.11"}, + {"52","14.1"}, + {"53","14.2"}, + {"54","14.3"}, + {"55","rsc"}, + {"56","14.4"}, + {"57","14.5"}, + {"58","rsc"}, + {"59","14.8"}, + {"59","14.9"}, + {"60","14.10"}, + {"61","15.1"}, + {"61","15.2"}, + {"62","15.3"}, + {"63","15.4"}, + {"64","15.5"}, + {"65","13.4"}, + {"66","13.5"}, + {"67","13.6"}, + {"68","8.6"}, + {"69","16.1"}, + {"70","16.2"}, + {"71","8.1"}, + {"72","8.3"}, + {"73","16.3"}, + {"74","16.4"}, + {"75","8.2"}, + {"76","16.5"}, + {"77","10.2"}, + {"78","16.6"}, + {"79","rsc"}, + {"80","rsc"}, + {"81","16.7"}, + {"82","14.7"}, + {"83","16.8"}, + {"84","rsc"}, + {"85","16.9"}, + {"86","16.10"}, + {"87","8.5"}, + {"87","19.1"}, + {"88","19.2"}, + {"89","19.3"}, + {"90","19.4"}, + {"91","19.5"}, + {"92","19.6"}, + {"93","19.7"}, + {"94","19.8"}, + {"95","19.9"}, + {"96","19.10"}, + {"97","19.11"}, + {"98","19.12"}, + {"98","19.13"}, + {"99","3.4"}, + {"100","19.14"}, + {"101","17.1"}, + {"101","17.2"}, + {"101","17.4"}, + {"102","17.5"}, + {"103","17.3"}, + {"104","rsc"}, + {"105","rsc"}, + {"106","17.6"}, + {"107","rsc"}, + {"108","18.1"}, + {"109","18.2"}, + {"109","18.3"}, + {"110","18.4"}, + {"111","6.4"}, + {"112","6.5"}, + {"113","rsc"}, + {"114","20.1"}, + {"115","20.2"}, + {"116","3.6"}, + {"117","20.3"}, + {"118","20.4"}, + {"119","20.5"}, + {"120","20.6"}, + {"121","rsc"}, + {"122","20.7"}, + {"123","20.8"}, + {"124","20.9"}, + {"125","20.10"}, + {"126","20.11"}, + {"127","20.12"} +}; + +std::pair Mutator0RuleChecks; + +std::multimap MC3EquivalencyMap; + +std::unordered_map SaferCPPEquivalencyMap; +/**********************************************************************************************************************/ +class MutatorLVL0Tests +{ + public: + MutatorLVL0Tests() {} + + void run(void) + { + + } + + private: + +}; +/**********************************************************************************************************************/ +class mutagenAncestryReport// : public Devi::XMLReportBase +{ + public: + mutagenAncestryReport(std::vector> __dss, std::vector __wps) : DoomedStrains(__dss), WeakPoints(__wps) + { + RootPointer = Doc.NewElement("mutagen:Report"); + RootPointer->SetAttribute("xmlns:mutagen", "http://www.w3.org/2001/XMLSchema"); + } + + ~mutagenAncestryReport() + { + Doc.InsertEndChild(RootPointer); + } + + virtual void AddNode(void) + { + XMLElement* MGene = Doc.NewElement("DoomedStrains"); + + for (auto &iter : DoomedStrains) + { + XMLElement* NodeDoomedStrain = Doc.NewElement("DoomedStrain"); + + for (auto &iterer : iter) + { + XMLElement* Child = Doc.NewElement("Strain"); + Child->SetText(iterer.c_str()); + NodeDoomedStrain->InsertEndChild(Child); + } + + MGene->InsertEndChild(NodeDoomedStrain); + } + + RootPointer->InsertEndChild(MGene); + } + + void AddNodeWeakPoint(void) + { + XMLElement* WeakStrain = Doc.NewElement("WeakStrains"); + + for (auto &iter : WeakPoints) + { + XMLElement* Child = Doc.NewElement("WeakStrain"); + Child->SetAttribute("WeakStrainType", iter.PlaceHolderStringForType.c_str()); + Child->SetAttribute("File", iter.File.c_str()); + Child->SetAttribute("LineNumber", iter.LineNumber); + Child->SetAttribute("ColumnNumber", iter.ColumnNumber); + WeakStrain->InsertEndChild(Child); + } + + RootPointer->InsertEndChild(WeakStrain); + } + +#if 1 + void CreateReport() + { + Doc.InsertFirstChild(RootPointer); + } + + void SaveReport(const char* __filename) + { + Doc.InsertEndChild(RootPointer); + + XMLError XMLErrorResult = Doc.SaveFile(__filename); + + if (XMLErrorResult != XML_SUCCESS) + { + std::cerr << "could not write xml misra report.\n"; + } + } +#endif + + private: + std::vector> DoomedStrains; + std::vector WeakPoints; +#if 1 + XMLElement* RootPointer; + XMLDocument Doc; +#endif +}; +/**********************************************************************************************************************/ +#define EXTRACT_MUTAGEN + +class MutagenExtraction +{ + public: + MutagenExtraction() {} + + ~MutagenExtraction() {} + + void ExtractAncestry(clang::ast_type_traits::DynTypedNode __dtn, clang::ASTContext &__astx) + { + clang::ASTContext::DynTypedNodeList DNL = __astx.getParents(__dtn); + if (DNL.empty()) return void(); + + /*FIXME-a LastStrain. obviously well end up losing some parents in cpp if we're just picking up the + * first parent from the list.*/ + LastStrain.push_back(DNL[0].getNodeKind().asStringRef().str()); + clang::ast_type_traits::DynTypedNode DTN = DNL[0]; + + /*FIXME-what does getparents return when there are no more parents to return?*/ + while (DTN.getNodeKind().asStringRef().str() != "FunctionDecl") + { + DNL = __astx.getParents(DTN); + if (DNL.empty()) return void(); + DTN = DNL[0]; + LastStrain.push_back(DTN.getNodeKind().asStringRef().str()); + } + + MutantStrainsAncestry.push_back(LastStrain); + LastStrain.clear(); + } + + void ExtractWeakPoints(SourceLocation __sl, SourceManager &__sm, std::string __type) + { + WeakPoint tmp = WeakPoint(__type, __sm.getFilename(__sl).str(), \ + __sm.getSpellingLineNumber(__sl), __sm.getSpellingColumnNumber(__sl)); + WeakPoints.push_back(tmp); + } + + void ExtractWeakPoints(FullSourceLoc __fsl, SourceLocation __sl, std::string __type) + { + WeakPoint tmp = WeakPoint(__type, __fsl.getManager().getFilename(__sl).str(), \ + __fsl.getSpellingLineNumber(), __fsl.getSpellingColumnNumber()); + WeakPoints.push_back(tmp); + } + + void ExtractWeakPoints(std::string __type, unsigned int __ln, unsigned int __cn, std::string __file) + { + WeakPoint tmp = WeakPoint(__type, __file, __ln, __cn); + WeakPoints.push_back(tmp); + } + + void DumpLast(void) + { + for (auto &iter : LastStrain) + { + std::cout << "DoomedStrain : " << iter << "\n"; + } + } + + void DumpAll(void) + { + for (auto &iter : MutantStrainsAncestry) + { + for (auto &iterer : iter) + { + std::cout << "DoomedStrainAll : " << iterer << "\n"; + } + + std::cout << "\n"; + } + } + + void XMLReportAncestry(void) + { + mutagenAncestryReport MAR(MutantStrainsAncestry, WeakPoints); + MAR.CreateReport(); + MAR.AddNode(); + MAR.AddNodeWeakPoint(); + MAR.SaveReport("m0.xml"); + } + + private: + std::vector LastStrain; + std::vector> MutantStrainsAncestry; + std::vector WeakPoints; +}; +/**********************************************************************************************************************/ +#endif +/**********************************************************************************************************************/ +/*last line intentionally left blank*/ + diff --git a/m0/mutator-lvl1.cpp b/m0/mutator-lvl1.cpp new file mode 100644 index 0000000..c6082f9 --- /dev/null +++ b/m0/mutator-lvl1.cpp @@ -0,0 +1,622 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ +/**********************************************************************************************************************/ +/*FIXME-all classes should use replacements.*/ +/**********************************************************************************************************************/ +/*included modules*/ +/*project headers*/ +#include "mutator_aux.h" +/*standard headers*/ +#include +#include +#include +/*LLVM headers*/ +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/Function.h" +/**********************************************************************************************************************/ +/*used namespaces*/ +using namespace llvm; +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::driver; +using namespace clang::tooling; +/**********************************************************************************************************************/ +/*global vars*/ +/*the variable that holds the previously-matched SOC for class StmtTrap.*/ +std::string g_linenoold; + +static llvm::cl::OptionCategory MutatorLVL1Cat("mutator-lvl1 options category"); +/**********************************************************************************************************************/ +/*matcher callback for something.*/ +class FunctionHandler : public MatchFinder::MatchCallback { +public: + FunctionHandler (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("binopeq") != nullptr) + { + /*get the matched node.*/ + const BinaryOperator *BinOp = MR.Nodes.getNodeAs("binopeq"); + + /*get the sourceloation.*/ + SourceLocation BinOpSL = BinOp->getLocStart(); + + BinOpSL = Devi::SourceLocationHasMacro(BinOpSL, Rewrite, "start"); + /*does the sourcelocation include a macro expansion?*/ + + /*replace it.*/ +#if 0 + Rewrite.ReplaceText(BinOpSL, 2U , "XXX"); +#endif + } + else + { + std::cout << "the macther -binopeq- returned nullptr!" << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class StmtTrapIf : public MatchFinder::MatchCallback { +public: + StmtTrapIf (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run (const MatchFinder::MatchResult &MR) + { + /*just in case*/ + if (MR.Nodes.getNodeAs("iftrap") != nullptr) + { + /*getting the matched ifStmt.*/ + const IfStmt *TrapIf = MR.Nodes.getNodeAs("iftrap"); + + /*getting the condition of the matched ifStmt.*/ + const Expr *IfCond = TrapIf->getCond(); + + /*getting the sourcerange of the condition of the trapped ifstmt.*/ + SourceLocation TrapIfCondSL = IfCond->getLocStart(); + TrapIfCondSL = Devi::SourceLocationHasMacro(TrapIfCondSL, Rewrite, "start"); + SourceLocation TrapIfCondSLEnd = IfCond->getLocEnd(); + TrapIfCondSLEnd = Devi::SourceLocationHasMacro(TrapIfCondSLEnd, Rewrite, "end"); + SourceRange TrapIfCondSR; + TrapIfCondSR.setBegin(TrapIfCondSL); + TrapIfCondSR.setEnd(TrapIfCondSLEnd); + + /*replacing the condition with the utility trap function.*/ +#if 0 + Rewrite.ReplaceText(TrapIfCondSR, "C_Trap_P()"); +#endif + } + else + { + std::cout << "the matcher -iftrap- returned nullptr!" << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class StmtTrap : public MatchFinder::MatchCallback { +public: + StmtTrap (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + /*if there are more than 2 statements in the traditional sense in one line, the behavior is undefined.*/ + /*for now this class only finds an SOC. later to be used for something useful.*/ + virtual void run (const MatchFinder::MatchResult &MR) + { + /*out of paranoia*/ + if (MR.Nodes.getNodeAs("stmttrap") != nullptr) + { + const Stmt *StmtTrapMR = MR.Nodes.getNodeAs("stmttrap"); + + SourceLocation STSL = StmtTrapMR->getLocStart(); + STSL = Devi::SourceLocationHasMacro(STSL, Rewrite, "start"); + SourceLocation STSLE = StmtTrapMR->getLocEnd(); + STSLE = Devi::SourceLocationHasMacro(STSLE, Rewrite, "end"); + + /*just getting the SOC of the matched statement out of its sourcelocation.*/ + /*this only works since we are guaranteed the same and known matching pattern by MatchFinder.*/ + size_t startloc = 0U; + size_t endloc = 0U; + std::string lineno; + startloc = STSL.printToString(*MR.SourceManager).find(":", 0U); + endloc = STSLE.printToString(*MR.SourceManager).find(":", startloc + 1U); + lineno = STSL.printToString(*MR.SourceManager).substr(startloc, endloc - startloc); + + /*just prints out the sourcelocations for diagnostics.*/ +#if 0 + std::cout << STSL.printToString(*MR.SourceManager) << std::endl; + std::cout << STSLE.printToString(*MR.SourceManager) << std::endl; + std::cout << startloc << "---" << endloc << "---" << lineno << std::endl; +#endif + + /*have we matched a new SOC? if yes:*/ + if (lineno != g_linenoold) + { + SourceRange SR; + SR.setBegin(StmtTrapMR->getLocStart()); + SR.setEnd(StmtTrapMR->getLocEnd()); + +#if 0 + Rewrite.InsertText(StmtTrapMR->getLocStart(), "XXX", "true", "true"); +#endif + } + else + { + /*intentionally left blank.*/ + } + + /*set the string representing the old SOC line number to the one matched now.*/ + g_linenoold = lineno; + } + else + { + std::cout << "the matcher -stmttrap- returned nullptr!" << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class StmtRet : public MatchFinder::MatchCallback +{ +public: + StmtRet (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run (const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("stmtret") != nullptr) + { + /*getting the returnstmt.*/ + const ReturnStmt *RetStmtMR = MR.Nodes.getNodeAs("stmtret"); + + /*getting the sourcerange of the matched returnstmt.*/ + SourceLocation RSMR = RetStmtMR->getLocStart(); + RSMR = Devi::SourceLocationHasMacro(RSMR, Rewrite, "start"); + SourceLocation RSMRE = RetStmtMR->getLocEnd(); + RSMRE = Devi::SourceLocationHasMacro(RSMRE, Rewrite, "end"); + SourceRange RSMRSR; + RSMRSR.setBegin(RSMR); + RSMRSR.setEnd(RSMRE); + +#if 0 + Rewrite.ReplaceText(RSMRSR, "C_Trap_P()"); +#endif + } + else + { + std::cout << "matcher -stmtret- returned nullptr." << std::endl; + } + } + +private: + Rewriter &Rewrite; + +}; +/**********************************************************************************************************************/ +class ForFixer : public MatchFinder::MatchCallback +{ +public: + ForFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + /*adds curly braces for forstmts that don't have it.*/ + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mrfor") != nullptr) + { + const ForStmt *MRFor = MR.Nodes.getNodeAs("mrfor"); + + Rewriter::RewriteOptions opts; + + SourceLocation MRForSL = MRFor->getBody()->getLocStart(); + MRForSL = Devi::SourceLocationHasMacro(MRForSL, Rewrite, "start"); + SourceLocation MRForSLE = MRFor->getBody()->getLocEnd(); + MRForSLE = Devi::SourceLocationHasMacro(MRForSLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(MRForSL); + SR.setEnd(MRForSLE); + + int RangeSize = Rewrite.getRangeSize(SR, opts); + + Rewrite.InsertText(MRForSL, "{\n", true, false); + /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ + /*line-terminating semicolons are not included in the matches.*/ + Rewrite.InsertTextAfterToken(MRForSL.getLocWithOffset(RangeSize), "\n}"); + } + else + { + std::cout << "matcher -mrfor- returned nullptr." << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class WhileFixer : public MatchFinder::MatchCallback +{ +public: + WhileFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + /*adds curly braces for whilestmts that don't have it.*/ + virtual void run (const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mrwhile") != nullptr) + { + const WhileStmt *MRWhile = MR.Nodes.getNodeAs("mrwhile"); + +#if 0 + std::cout << MRWhile->getBody()->getLocStart().printToString(*MR.SourceManager) << std::endl; + std::cout << MRWhile->getBody()->getLocEnd().printToString(*MR.SourceManager) << std::endl; +#endif + + SourceLocation WFSL = MRWhile->getBody()->getLocStart(); + WFSL = Devi::SourceLocationHasMacro(WFSL, Rewrite, "start"); + SourceLocation WFSLE = MRWhile->getBody()->getLocEnd(); + WFSLE = Devi::SourceLocationHasMacro(WFSLE, Rewrite, "end"); + + /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ + /*line-terminating semicolons are not included in the matches.*/ + Rewrite.InsertText(WFSL, "{\n", true, true); + Rewrite.InsertTextAfterToken(WFSLE.getLocWithOffset(2U), "\n}"); + } + else + { +#if 1 + std::cout << "matcher -mrwhile- returned nullptr." << std::endl; +#endif + } + } + + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class IfElseFixer : public MatchFinder::MatchCallback +{ +public: + IfElseFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + /*underdev*/ + if (MR.Nodes.getNodeAs("mrifelse") != nullptr) + { + const IfStmt *ElseIf = MR.Nodes.getNodeAs("mrifelse"); + //const IfStmt *LastIf = MR.Nodes.getNodeAs("mrifelse"); + + SourceLocation IFESL = ElseIf->getElse()->getLocStart(); + IFESL = Devi::SourceLocationHasMacro(IFESL, Rewrite, "start"); + SourceLocation IFESLE = ElseIf->getElse()->getLocEnd(); + IFESLE = Devi::SourceLocationHasMacro(IFESLE, Rewrite, "end"); + SourceRange SR; + SR.setBegin(IFESL); + SR.setEnd(IFESLE); + + clang::Rewriter::RewriteOptions opts; + + int RangeSize = Rewrite.getRangeSize(SR, opts); + + //std::cout << IFESLE.printToString(*MR.SourceManager) << "\n" << std::endl; + +#if 1 + Rewrite.InsertText(IFESL, "{\n", true, true); + Rewrite.InsertTextAfterToken(IFESL.getLocWithOffset(RangeSize), "\n}"); +#endif + } + else + { + std::cout << "matcher -mrifelse- returned nullptr." << std::endl; + } + } + + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class IfFixer : public MatchFinder::MatchCallback +{ +public: + IfFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + /*adds curly braces to ifstmts that dont have it.*/ + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mrif") != nullptr) + { + const IfStmt *MRIf = MR.Nodes.getNodeAs("mrif"); + + SourceLocation FFSL = MRIf->getThen()->getLocStart(); + FFSL = Devi::SourceLocationHasMacro(FFSL, Rewrite, "start"); + SourceLocation FFSLE = MRIf->getThen()->getLocEnd(); + FFSLE = Devi::SourceLocationHasMacro(FFSLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(FFSL); + SR.setEnd(FFSLE); + Rewriter::RewriteOptions opts; + int RangeSize = Rewrite.getRangeSize(SR, opts); + + /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ + /*line-terminating semicolons are not included in the matches.*/ +#if 1 + Rewrite.InsertText(FFSL, "{\n", true, true); + Rewrite.InsertTextAfterToken(FFSL.getLocWithOffset(RangeSize), "\n}"); +#endif + } + else + { + std::cout << "matcher -mrif- returned nullptr." << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class SwitchFixer : public MatchFinder::MatchCallback +{ +public: + SwitchFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("bubba-hotep") != nullptr) + { + const CaseStmt *CS = MR.Nodes.getNodeAs("bubba-hotep"); + + const Stmt *SB = CS->getSubStmt(); + + SourceLocation SBSL = SB->getLocStart(); + SBSL = Devi::SourceLocationHasMacro(SBSL, Rewrite, "start"); + SourceLocation SBSLE = SB->getLocEnd(); + SBSLE = Devi::SourceLocationHasMacro(SBSLE, Rewrite, "end"); + + SourceLocation SL = CS->getLocStart(); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SourceLocation SLE = CS->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + Rewriter::RewriteOptions opts; + int RangeSize [[maybe_unused]] = Rewrite.getRangeSize(SR, opts); + +#if 1 + Rewrite.InsertText(SBSL, "{\n", true, true); + Rewrite.InsertTextAfterToken(SL.getLocWithOffset(RangeSize), "\n}"); +#endif + } + else + { + std::cout << "matcher -bubba-hotep- returned nullptr." << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class SwitchDfFixer : public MatchFinder::MatchCallback +{ +public: + SwitchDfFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("mumma-hotep") != nullptr) + { + const DefaultStmt *DS = MR.Nodes.getNodeAs("mumma-hotep"); + + const Stmt *SB = DS->getSubStmt(); + + SourceLocation CSL = SB->getLocStart(); + CSL = Devi::SourceLocationHasMacro(CSL, Rewrite, "start"); + + SourceLocation SL = DS->getLocStart(); + SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); + SourceLocation SLE = DS->getLocEnd(); + SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); + + SourceRange SR; + SR.setBegin(SL); + SR.setEnd(SLE); + Rewriter::RewriteOptions opts; + int RangeSize [[maybe_unused]] = Rewrite.getRangeSize(SR, opts); + +#if 1 + Rewrite.InsertText(CSL, "{\n", true, true); + Rewrite.InsertTextAfterToken(SL.getLocWithOffset(RangeSize), "\n}"); +#endif + } + else + { + std::cout << "matcher -mumma-hotep- returned nullptr." << std::endl; + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class IfConstSwapper : public MatchFinder::MatchCallback +{ +public: + IfConstSwapper (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("ifconstswapbinop") != nullptr) + { + const BinaryOperator* BO = MR.Nodes.getNodeAs("ifconstswapbinop"); + + const Expr* LHS = BO->getLHS(); + const Expr* RHS = BO->getRHS(); + + ASTContext *const ASTC = MR.Context; + SourceManager *const SM = MR.SourceManager; + + if (RHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects) && !LHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects)) + { + SourceLocation SLLHS = LHS->getLocStart(); + SLLHS = Devi::SourceLocationHasMacro(SLLHS, Rewrite, "start"); + SourceLocation SLELHS = LHS->getLocStart(); + SLELHS = Devi::SourceLocationHasMacro(SLELHS, Rewrite, "end"); + SourceRange SRLHS; + SRLHS.setBegin(SLLHS); + SRLHS.setEnd(SLELHS); + + if (!SM->isInMainFile(SLLHS)) + { + return void(); + } + + if (SM->isInSystemHeader(SLLHS)) + { + return void(); + } + + SourceLocation SLRHS = RHS->getLocStart(); + SLRHS = Devi::SourceLocationHasMacro(SLRHS, Rewrite, "start"); + SourceLocation SLERHS = RHS->getLocEnd(); + SLERHS = Devi::SourceLocationHasMacro(SLERHS, Rewrite, "end"); + SourceRange SRRHS; + SRRHS.setBegin(SLRHS); + SRRHS.setEnd(SLERHS); + + const std::string LHSString = Rewrite.getRewrittenText(SRLHS); + const std::string RHSString = Rewrite.getRewrittenText(SRRHS); + +#if 0 + std::cout << "lhs:" << LHSString << " " << "rhs:" << RHSString << " " << SLLHS.printToString(*SM) << std::endl; +#endif + + StringRef LHSRef = StringRef(LHSString); + StringRef RHSRef = StringRef(RHSString); + + Rewriter::RewriteOptions opts; + int RangeSizeLHS = Rewrite.getRangeSize(SRLHS, opts); + int RangeSizeRHS = Rewrite.getRangeSize(SRRHS, opts); + + Rewrite.ReplaceText(SRLHS.getBegin(), RangeSizeLHS, RHSRef); + Rewrite.ReplaceText(SRRHS.getBegin(), RangeSizeRHS, LHSRef); + } + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class MyASTConsumer : public ASTConsumer { + +public: + MyASTConsumer(Rewriter &R) : HandlerForFunction(R), HandlerForIfTrap(R), HandlerForStmtTrap(R), HandlerForStmtRet(R), HandlerForFixer(R), \ + HandlerForWhile(R), HandlerForIfElse(R), HandlerForIfFixer(R), HandlerForSwitchFixer(R), HandlerForSwitchDf(R), HandlerForIfConstSwap(R) + { + Matcher.addMatcher(binaryOperator(hasOperatorName("==")).bind("binopeq"), &HandlerForFunction); + + Matcher.addMatcher(ifStmt(hasCondition(anything())).bind("iftrap"), &HandlerForIfTrap); + + Matcher.addMatcher(stmt().bind("stmttrap") , &HandlerForStmtTrap); + + Matcher.addMatcher(returnStmt().bind("stmtret"), &HandlerForStmtRet); + + Matcher.addMatcher(forStmt(unless(hasDescendant(compoundStmt()))).bind("mrfor"), &HandlerForFixer); + + Matcher.addMatcher(whileStmt(unless(hasDescendant(compoundStmt()))).bind("mrwhile"), &HandlerForWhile); + + Matcher.addMatcher(ifStmt(allOf(hasElse(unless(ifStmt())), hasElse(unless(compoundStmt())))).bind("mrifelse"), &HandlerForIfElse); + + Matcher.addMatcher(ifStmt(unless(hasDescendant(compoundStmt()))).bind("mrif"), &HandlerForIfFixer); + + Matcher.addMatcher(switchStmt(forEachDescendant(caseStmt(unless(hasDescendant(compoundStmt()))).bind("bubba-hotep"))), &HandlerForSwitchFixer); + + Matcher.addMatcher(switchStmt(hasDescendant(defaultStmt(unless(hasDescendant(compoundStmt()))).bind("mumma-hotep"))), &HandlerForSwitchDf); + + Matcher.addMatcher(ifStmt(has(binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("="))).bind("ifconstswapbinop"))).bind("ifconstswapper"), &HandlerForIfConstSwap); + } + + void HandleTranslationUnit(ASTContext & Context) override { + Matcher.matchAST(Context); + } + +private: + FunctionHandler HandlerForFunction; + StmtTrapIf HandlerForIfTrap; + StmtTrap HandlerForStmtTrap; + StmtRet HandlerForStmtRet; + ForFixer HandlerForFixer; + WhileFixer HandlerForWhile; + IfElseFixer HandlerForIfElse; + IfFixer HandlerForIfFixer; + SwitchFixer HandlerForSwitchFixer; + SwitchDfFixer HandlerForSwitchDf; + IfConstSwapper HandlerForIfConstSwap; + MatchFinder Matcher; +}; +/**********************************************************************************************************************/ +class MyFrontendAction : public ASTFrontendAction +{ +public: + MyFrontendAction() {} + void EndSourceFileAction() override + { + TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); + } + + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override + { + TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); + return llvm::make_unique(TheRewriter); + } + +private: + Rewriter TheRewriter; +}; +/**********************************************************************************************************************/ +/*Main*/ +int main(int argc, const char **argv) +{ + CommonOptionsParser op(argc, argv, MutatorLVL1Cat); + ClangTool Tool(op.getCompilations(), op.getSourcePathList()); + + return Tool.run(newFrontendActionFactory().get()); +} +/*last line intentionally left blank.*/ diff --git a/m0/mutator-lvl2.cpp b/m0/mutator-lvl2.cpp new file mode 100644 index 0000000..c585734 --- /dev/null +++ b/m0/mutator-lvl2.cpp @@ -0,0 +1,120 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ +/**********************************************************************************************************************/ +/*FIXME-all classes should use replacements.*/ +/**********************************************************************************************************************/ +/*included modules*/ +/*project headers*/ +//#include "mutator_aux.h" +/*standard headers*/ +#include +#include +#include +/*LLVM headers*/ +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/LLVM.h" +#include "clang/CodeGen/CodeGenAction.h" +#include "clang/CodeGen/BackendUtil.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Function.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Linker/Linker.h" +/**********************************************************************************************************************/ +/*used namespaces*/ +using namespace llvm; +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::driver; +using namespace clang::tooling; +/**********************************************************************************************************************/ +/*global vars*/ +static llvm::cl::OptionCategory MatcherSampleCategory("Matcher Sample"); +/**********************************************************************************************************************/ +class BlankDiagConsumer : public clang::DiagnosticConsumer +{ + public: + BlankDiagConsumer() = default; + virtual ~BlankDiagConsumer() {} + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override {} +}; +/**********************************************************************************************************************/ +class MyASTConsumer : public ASTConsumer { +public: + MyASTConsumer(Rewriter &R) { + } + + void HandleTranslationUnit(ASTContext &Context) { + std::cout << "i was here\n"; + //Matcher.matchAST(Context); + } + +private: + MatchFinder Matcher; +}; +/**********************************************************************************************************************/ +class MyFrontendAction : public ASTFrontendAction { +public: + MyFrontendAction() {} + void EndSourceFileAction() override { + //TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); + } + + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override { + DiagnosticsEngine &DE = CI.getPreprocessor().getDiagnostics(); + DE.setClient(BDCProto, false); + TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); + //return llvm::make_unique(new MyASTConsumer(TheRewriter)); + //return llvm::make_unique(*new MyASTConsumer(TheRewriter)); + return llvm::make_unique(TheRewriter); + //return std::unique_ptr(new ASTConsumer); + } + +private: + BlankDiagConsumer* BDCProto = new BlankDiagConsumer; + Rewriter TheRewriter; +}; +/**********************************************************************************************************************/ +/*Main*/ +int main(int argc, const char **argv) { + CommonOptionsParser op(argc, argv, MatcherSampleCategory); + ClangTool Tool(op.getCompilations(), op.getSourcePathList()); + + int ret; + ret = Tool.run(newFrontendActionFactory().get()); + std::cout << "fucking done!\n"; + return ret; +} +/*last line intentionally left blank.*/ + diff --git a/m0/mutator_aux.cpp b/m0/mutator_aux.cpp new file mode 100644 index 0000000..83211f5 --- /dev/null +++ b/m0/mutator_aux.cpp @@ -0,0 +1,151 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*********************************************************************************************************************/ +/*inclusion directives*/ +#include "mutator_aux.h" +#include +#include +#include +#include +#include "clang/AST/AST.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "../tinyxml2/tinyxml2.h" +#include "../json/json.hpp" +/*********************************************************************************************************************/ +using namespace clang; +/*********************************************************************************************************************/ +namespace Devi { +/*a simple function that checks the sourcelocations for a macro expansion. returns the sourcelocation without +macro expansion address.*/ +#if 1 +SourceLocation SourceLocationHasMacro [[deprecated("doesnt work")]] (SourceLocation SL, Rewriter &Rewrite, std::string Kind) { + /*does the sourcelocation include a macro expansion?*/ + if ( SL.isMacroID()) { + /*get the expansion range which is startloc and endloc*/ + std::pair expansionRange = Rewrite.getSourceMgr().getImmediateExpansionRange(SL); + if (Kind == "start") { + return (expansionRange.first); + } else if (Kind == "end") { + return (expansionRange.second); + } else { + std::cout << "the third argument of Devi::SourceLocationHasMacro is invalid." << std::endl; + } + } else { + return (SL); + } + return (SL); +} +#endif + +SourceLocation SourceLocationHasMacro(SourceLocation __sl, Rewriter &__rewrite) { + if (__sl.isMacroID()) { + return __rewrite.getSourceMgr().getSpellingLoc(__sl); + } else { + return __sl; + } +} + +SourceLocation getSLSpellingLoc(SourceLocation __sl, Rewriter &__rewrite) { + if (__sl.isMacroID()) return __rewrite.getSourceMgr().getSpellingLoc(__sl); + else return __sl; +} +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +/*the first argument is the option SysHeader from the mutator-lvl0 cl.*/ +bool IsTheMatchInSysHeader(bool SysHeaderFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) { + ASTContext *const ASTC = MR.Context; + const SourceManager &SM = ASTC->getSourceManager(); + + if (SM.isInSystemHeader(SL) && !SysHeaderFlag) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInSysHeader(bool SysHeaderFlag, const SourceManager &SM, SourceLocation SL) { + if (SM.isInSystemHeader(SL) && !SysHeaderFlag) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader, SourceLocation SL) { + if (SysHeader && !SysHeaderFlag) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader) +{ + if (SysHeader && !SysHeaderFlag) { + return true; + } else { + return false; + } +} +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +bool IsTheMatchInMainFile(bool MainFileFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) { + ASTContext *const ASTC = MR.Context; + const SourceManager &SM = ASTC->getSourceManager(); + if (SM.isInMainFile(SL) || (!SM.isInMainFile(SL) && !MainFileFlag)) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInMainFile(bool MainFileFlag, const SourceManager &SM, SourceLocation SL) { + if (SM.isInMainFile(SL) || (!SM.isInMainFile(SL) && !MainFileFlag)) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile, SourceLocation SL) { + if (MainFile || (!MainFile && !MainFileFlag)) { + return true; + } else { + return false; + } +} + +bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile) { + if (MainFile || (!MainFile && !MainFileFlag)) { + return true; + } else { + return false; + } +} +/*********************************************************************************************************************/ +/*End of namespace Devi*/ +} +/*********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/m0/mutator_aux.h b/m0/mutator_aux.h new file mode 100644 index 0000000..9f22a5a --- /dev/null +++ b/m0/mutator_aux.h @@ -0,0 +1,66 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*********************************************************************************************************************/ +/*first line intentionally left blank*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*********************************************************************************************************************/ +/*inclusion guard*/ +#ifndef MUTATOR_AUX_H +#define MUTATOR_AUX_H +/*********************************************************************************************************************/ +/*inclusion directives*/ +#include +#include +#include "clang/AST/AST.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Rewrite/Core/Rewriter.h" +/*********************************************************************************************************************/ +/*Macros and definitions*/ +#define CheckSLValidity(SL) \ + do {\ + if (!SL.isValid()) {return void();}}\ + while(0); +/*********************************************************************************************************************/ +using namespace clang; +/*********************************************************************************************************************/ +namespace Devi { +enum class NodeKind {NoValue, VarDecl, FieldDecl, RecordDecl, LabelDecl, FunctionDecl, TypedefDecl, ParmVarDecl, EnumDecl, EnumConstDecl}; +enum class Scope {NoValue, TU, Block}; +enum class FunctionDeclKind {NoValue, Definition, Declaration}; +/*********************************************************************************************************************/ +SourceLocation SourceLocationHasMacro(SourceLocation SL, Rewriter &Rewrite, std::string Kind); +SourceLocation SourceLocationHasMacro(SourceLocation __sl, Rewriter &__rewrite); +SourceLocation getSLSpellingLoc(SourceLocation __sl, Rewriter &__rewrite); +/*********************************************************************************************************************/ +bool IsTheMatchInSysHeader(bool SysHeaderFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL); +bool IsTheMatchInSysHeader(bool SysHeaderFlag, const SourceManager &SM, SourceLocation SL); +bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader, SourceLocation SL); +bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader); +/*********************************************************************************************************************/ +bool IsTheMatchInMainFile(bool MainFileFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL); +bool IsTheMatchInMainFile(bool MainFileFlag, const SourceManager &SM, SourceLocation SL); +bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile, SourceLocation SL); +bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile); +/*********************************************************************************************************************/ +/*end of namespace Devi*/ +} +#endif +/*********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/m0/mutator_report.cpp b/m0/mutator_report.cpp new file mode 100644 index 0000000..1e0459f --- /dev/null +++ b/m0/mutator_report.cpp @@ -0,0 +1,314 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*********************************************************************************************************************/ +/*inclusion directives*/ +#include "mutator_report.h" +#include +#include +#include +#include +#include "clang/AST/AST.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "../tinyxml2/tinyxml2.h" +#include "../json/json.hpp" +/*********************************************************************************************************************/ +using namespace clang; +using namespace tinyxml2; +using json = nlohmann::json; +/*********************************************************************************************************************/ +namespace Devi { +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +/****************************************************XMLReportBase****************************************************/ + XMLReportBase::XMLReportBase() + { + RootPointer = Doc.NewElement("mutagen:Report"); + RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema"); + } + + XMLReportBase::~XMLReportBase() + { + Doc.InsertEndChild(RootPointer); + } + + void XMLReportBase::CreateReport() + { + Doc.InsertFirstChild(RootPointer); + } + + void XMLReportBase::SaveReport(const char* __filename) + { + Doc.InsertEndChild(RootPointer); + + XMLError XMLErrorResult = Doc.SaveFile(__filename); + + if (XMLErrorResult != XML_SUCCESS) + { + std::cerr << "could not write xml misra report(base).\n"; + } + } +/************************************************end of XMLReportBase*************************************************/ +/*********************************************************************************************************************/ +/******************************************************XMLReport******************************************************/ +XMLReport::XMLReport() +{ + RootPointer = XMLReportDoc.NewElement("mutator:Report"); + RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema"); +} + +XMLReport::~XMLReport() +{ + XMLReportDoc.InsertEndChild(RootPointer); +} + +void XMLReport::XMLCreateReport() +{ + XMLReportDoc.InsertFirstChild(RootPointer); +} + +/*it is the caller's responsibility to make sure the sourcelocation passed to this overload of the member function +contains only the spelling location.*/ +void XMLReport::XMLAddNode(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(1) of XMLAddNode is not valid."); + + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + unsigned LineNumber = FSL.getSpellingLineNumber(); + unsigned ColumnNumber = FSL.getSpellingColumnNumber(); + + const SourceManager& SM = FSL.getManager(); + std::string FileNameString = SM.getFilename(SL).str(); + + XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); + MisraElement->SetText(Description.c_str()); + MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); + MisraElement->SetAttribute("FileName", FileNameString.c_str()); + MisraElement->SetAttribute("SpellingLineNumber", LineNumber); + MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); + RootPointer->InsertEndChild(MisraElement); +} + +void XMLReport::XMLAddNode(FullSourceLoc FullSrcLoc, SourceLocation SL, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(2) of XMLAddNode is not valid."); + + unsigned LineNumber = FullSrcLoc.getSpellingLineNumber(); + unsigned ColumnNumber = FullSrcLoc.getSpellingColumnNumber(); + + const SourceManager& SM = FullSrcLoc.getManager(); + std::string FileNameString = SM.getFilename(SL).str(); + + XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); + MisraElement->SetText(Description.c_str()); + MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); + MisraElement->SetAttribute("FileName", FileNameString.c_str()); + MisraElement->SetAttribute("SpellingLineNumber", LineNumber); + MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); + RootPointer->InsertEndChild(MisraElement); +} + +void XMLReport::XMLAddNode(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description) +{ + SL = SM.getSpellingLoc(SL); + + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + unsigned LineNumber = SM.getSpellingLineNumber(SL); + unsigned ColumnNumber = SM.getSpellingColumnNumber(SL); + + std::string FileNameString = SM.getFilename(SL).str(); + + XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); + MisraElement->SetText(Description.c_str()); + MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); + MisraElement->SetAttribute("FileName", FileNameString.c_str()); + MisraElement->SetAttribute("SpellingLineNumber", LineNumber); + MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); + RootPointer->InsertEndChild(MisraElement); +} + +void XMLReport::XMLAddNode(std::string FilePath, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); + MisraElement->SetText(Description.c_str()); + MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); + MisraElement->SetAttribute("FileName", FilePath.c_str()); + RootPointer->InsertEndChild(MisraElement); +} + +void XMLReport::XMLAddNode(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); + MisraElement->SetText(Description.c_str()); + MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); + MisraElement->SetAttribute("FileName", FileName.c_str()); + MisraElement->SetAttribute("SpellingLineNumber", Line); + MisraElement->SetAttribute("SpellingColumnNumber", Column); + RootPointer->InsertEndChild(MisraElement); +} + +bool XMLReport::isReportEmpty(void) +{ + return false; +} + +void XMLReport::SaveReport(void) +{ + if(this->isReportEmpty()) + { + return void(); + } + + XMLReportDoc.InsertEndChild(RootPointer); + + XMLError XMLErrorResult = XMLReportDoc.SaveFile("./misrareport.xml"); + + if (XMLErrorResult != XML_SUCCESS) + { + std::cerr << "could not write xml misra report.\n"; + } +} +/***************************************************End of XMLReport**************************************************/ +/*********************************************************************************************************************/ +/*****************************************************JSONReport******************************************************/ +JSONReport::JSONReport() {} + +void JSONReport::JSONCreateReport(void) +{ + JSONRepFile.open("./test/misrareport.json", std::ios::out); +} + +void JSONReport::JSONAddElement(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(1) of JSONAddElement is not valid."); + + FullSourceLoc FSL = ASTC->getFullLoc(SL); + + unsigned LineNumber = FSL.getSpellingLineNumber(); + unsigned ColumnNumber = FSL.getSpellingColumnNumber(); + + const SourceManager& SM = FSL.getManager(); + std::string FileNameString = SM.getFilename(SL).str(); + + json RepJ; + + RepJ["MisraDiag"]["Description"] = Description.c_str(); + RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); + RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); + RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; + RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; + + JSONRepFile << RepJ << std::endl; +} + +void JSONReport::JSONAddElement(FullSourceLoc FullSrcLoc, SourceLocation SL, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(2) of XMLAddNode is not valid."); + + unsigned LineNumber = FullSrcLoc.getSpellingLineNumber(); + unsigned ColumnNumber = FullSrcLoc.getSpellingColumnNumber(); + + const SourceManager& SM = FullSrcLoc.getManager(); + std::string FileNameString = SM.getFilename(SL).str(); + + json RepJ; + + RepJ["MisraDiag"]["Description"] = Description.c_str(); + RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); + RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); + RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; + RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; + + JSONRepFile << RepJ << std::endl; +} + +void JSONReport::JSONAddElement(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description) +{ + SL = SM.getSpellingLoc(SL); + + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + unsigned LineNumber = SM.getSpellingLineNumber(SL); + unsigned ColumnNumber = SM.getSpellingColumnNumber(SL); + + std::string FileNameString = SM.getFilename(SL).str(); + + json RepJ; + + RepJ["MisraDiag"]["Description"] = Description.c_str(); + RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); + RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); + RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; + RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; + + JSONRepFile << RepJ << std::endl; +} + +void JSONReport::JSONAddElement(std::string FilePath, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + json RepJ; + + RepJ["MisraDiag"]["Description"] = Description.c_str(); + RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); + RepJ["MisraDiag"]["FileName"] = FilePath.c_str(); + + + JSONRepFile << RepJ << std::endl; +} + +void JSONReport::JSONAddElement(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description) +{ + //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); + + json RepJ; + + RepJ["MisraDiag"]["Description"] = Description.c_str(); + RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); + RepJ["MisraDiag"]["FileName"] = FileName.c_str(); + RepJ["MisraDiag"]["SpellingLineNumber"] = Line; + RepJ["MisraDiag"]["SpellingColumnNumber"] = Column; + + JSONRepFile << RepJ << std::endl; +} + +void JSONReport::CloseReport(void) +{ + JSONRepFile.close(); +} +/*********************************************************************************************************************/ +/*************************************************End Of JSONReport***************************************************/ +/*********************************************************************************************************************/ + +/*********************************************************************************************************************/ +/*End of namespace Devi*/ +/*********************************************************************************************************************/ +} +/*********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/m0/mutator_report.h b/m0/mutator_report.h new file mode 100644 index 0000000..0be06f6 --- /dev/null +++ b/m0/mutator_report.h @@ -0,0 +1,117 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*********************************************************************************************************************/ +/*first line intentionally left blank*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*********************************************************************************************************************/ +/*inclusion guard*/ +#ifndef MUTATOR_REPORT_H +#define MUTATOR_REPORT_H +/*********************************************************************************************************************/ +/*inclusion directives*/ +#include +#include +#include "clang/AST/AST.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "../tinyxml2/tinyxml2.h" +/*********************************************************************************************************************/ +using namespace clang; +using namespace tinyxml2; +/*********************************************************************************************************************/ +namespace Devi { +/*********************************************************************************************************************/ + class XMLReportBase + { + public: + XMLReportBase(); + virtual ~XMLReportBase(); + + void CreateReport(void); + + virtual void AddNode(void) = 0; + + void SaveReport(const char*); + + protected: + XMLDocument Doc; + XMLElement* RootPointer; + }; +/*********************************************************************************************************************/ + /*@DEVI- for both report classes, if the program gets terminated, since the destructor does not close + the report files, what happens to them is implementation-defined in case of let's say an exit, but since + we erase the files everytime a new instance of mutator-lvl0 is called, we are fine. or so i think.*/ + /*@DEVI- in case of a crash, the XML report will only hold the base node, while the JSON report will + contain all the reports up until the crash. tinyxml2 writes the nodes to file on SaveFile which is + called in SaveReport so that's why.*/ + class XMLReport + { + public: + XMLReport(); + ~XMLReport(); + + void XMLCreateReport(void); + void XMLAddNode(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description); + /*overloaded for rule checks that announce the result on onendoftranslation instead of run + since they dont have access to matchresult or astcontext.*/ + void XMLAddNode(FullSourceLoc FSL, SourceLocation SL, std::string MisraRule, std::string Description); + /*another overload to support the xml output for PPCallbacks.*/ + void XMLAddNode(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description); + + void XMLAddNode(std::string FilePath, std::string MisraRule, std::string Description); + + void XMLAddNode(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description); + + bool isReportEmpty(void); + + void SaveReport(void); + + private: + XMLDocument XMLReportDoc; + XMLElement* RootPointer; + }; +/*********************************************************************************************************************/ + class JSONReport + { + public: + JSONReport(); + + void JSONCreateReport(void); + void JSONAddElement(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description); + /*overload for checks that announce the result in onendoftranslation unit.*/ + void JSONAddElement(FullSourceLoc FSL, SourceLocation SL, std::string MisraRule, std::string Description); + /*overload for PPCallbacks.*/ + void JSONAddElement(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description); + + void JSONAddElement(std::string FilePath, std::string MisraRule, std::string Description); + + void JSONAddElement(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description); + + void CloseReport(void); + + private: + std::ofstream JSONRepFile; + }; +/*********************************************************************************************************************/ +/*********************************************************************************************************************/ +} //end of namespace devi +#endif +/*********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/makefile b/makefile index ede3200..ece81c4 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,5 @@ -######################################INCLUDES################################# include macros.mk -#######################################VARS#################################### -EXTRA_LD_FLAGS+=tinyxml2/tinyxml2.o TARGET0=mutator-lvl0 TARGET1=mutator-lvl1 @@ -13,35 +10,21 @@ TARGETS=mutatorserver SFCPP01=safercpp-arr BRUISER=bruiser OBSC=obfuscator -SRCS=$(wildcard *.cpp) -######################################RULES#################################### -.DEFAULT: all - -.PHONY:all clean install help TAGS $(BRUISER) $(OBSC) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) - -all: $(TARGET0) $(TARGET1) $(TARGET2) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) $(BRUISER) $(OBSC) - -depend:.depend -.depend:$(SRCS) - rm -f ./.depend - $(CXX) -MM $(CXX_FLAGS) $^ > ./.depend +.DEFAULT: all --include ./.depend +.PHONY:all clean install help $(BRUISER) $(OBSC) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) -.cpp.o: - $(CXX) $(CXX_FLAGS) -c $< -o $@ - $(MAKE) -C tinyxml2 CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) - $(MAKE) -C json CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) +all: $(TARGET0) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) $(BRUISER) $(OBSC) -$(TARGET1): $(TARGET1).o mutator_aux.o +$(TARGET1): $(CXX) $^ $(LD_FLAGS) -o $@ -$(TARGET2): $(TARGET2).o mutator_aux.o +$(TARGET2): $(CXX) $^ $(LD_FLAGS) -o $@ -$(TARGET0): $(TARGET0).o mutator_aux.o mutator_report.o - $(CXX) $^ $(LD_FLAGS) -o $@ +$(TARGET0): + $(MAKE) -C m0 CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) $(SFCPP01): $(MAKE) -C safercpp CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) @@ -61,18 +44,14 @@ $(TARGETD): $(TARGETS): $(MAKE) -C daemon mutatorserver -TAGS: $(SRCS) - $(CTAGS) $(SRCS) - clean: - rm -f *.o *~ $(TARGET0) $(TARGET1) $(TARGET2) - rm ./.depend $(MAKE) -C tinyxml2 clean $(MAKE) -C json clean $(MAKE) -C daemon clean $(MAKE) -C safercpp clean $(MAKE) -C bruiser clean $(MAKE) -C obfuscator clean + $(MAKE) -C m0 clean install: chmod +x ./mutator.sh @@ -88,20 +67,4 @@ install: $(shell echo MUTATOR_HOME=$$(pwd) > ./daemon/mutator.config) help: - @echo '- There is help.' - @echo '- All is the default.' - @echo '- install makes the scripts executable. Also creates the reliquary.' - @echo '- Clean.' - @echo '- TAGS will run ctags on the C/C++ source files.' - @echo '- You can use the target names as build targets to just build one executable.' - @echo '- LLVM_CONF will tell the makefile the name of llvm-config. llvm-config is the default.' - @echo '- CXX will let you set the compiler. currently the only accepted values are clang++ and g++. clang++ is the default.' - @echo '- BUILD_MODE will let you choose to build for different coverage formats. the default is COV_NO_CLANG. the supported values are:' - @echo ' COV_USE: adds the clang -fprofile-instr-use option(clang++ only mode).' - @echo ' COV_GEN: adds the clang -fprofile-instr-generate option(clang++ only mode).' - @echo ' COV_GNU: generates coverage for the build compatible with gcov(clang++ only mode).' - @echo ' COV_NO_CLANG: this build mode will not support any coverage format and is meant to be used with clang++(clang++ only mode).' - @echo ' COV_NO_CLANG_1Z: does not instrument the code for any coverage and uses -std=c++1z (clang++ only mode).' - @echo ' GNU_MODE: meant to be used for builds with g++. supports no coverage(g++ only mode).' - @echo ' WIN_MODE: to support windows builds' - @echo '- Press tab for more targets if you have zsh!' + @echo "Under Construction" diff --git a/mutator-lvl0.cpp b/mutator-lvl0.cpp deleted file mode 100644 index 53b3ac5..0000000 --- a/mutator-lvl0.cpp +++ /dev/null @@ -1,8710 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*the source code for the static checks(Misra-C,...)*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ -/**********************************************************************************************************************/ -/*included modules*/ -/*project headers*/ -#include "mutator-lvl0.h" -#include "mutator_aux.h" -#include "mutator_report.h" -/*standard headers*/ -#include -#include -#include -#include -#include -#include -#include -#include -/*Clang headers*/ -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTTypeTraits.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Type.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/OperatorKinds.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/MacroArgs.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PPCallbacks.h" -#include "clang/Tooling/CommonOptionsParser.h" -//#include "clang/Tooling/Core/QualTypeNames.h" -#include "clang/Tooling/Tooling.h" -#include "clang/Rewrite/Core/Rewriter.h" -/*LLVM headers*/ -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/APInt.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/IR/Function.h" -/**********************************************************************************************************************/ -/*used namespaces*/ -using namespace llvm; -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::driver; -using namespace clang::tooling; -/**********************************************************************************************************************/ -/*macros and defs*/ - -/*@DEVI-disbale debugs info printouts.*/ -#define _MUT0_TEST -#if 1 -#undef _MUT0_TEST -#endif - -/*@DEVI-disbale all matchers.*/ -#define _MUT0_EN_MATCHERS -#if 0 -#undef _MUT0_EN_MATCHERS -#endif -/**********************************************************************************************************************/ -/*global vars*/ -Devi::XMLReport XMLDocOut; -Devi::JSONReport JSONDocOUT; -MutagenExtraction ME; - -std::vector MacroDefSourceLocation; -std::vector MacroUndefSourceLocation; -std::vector MacroNameString; -std::vector IncludeFileArr; - -/**********************************************************************************************************************/ -struct MutExHeaderNotFound : public std::exception -{ -public: - MutExHeaderNotFound(std::string FileName) : FName(FileName) {} - - const char* what () const throw() - { - return "Header Not Found"; - } - - std::string getFileName() const - { - return FName; - } - -private: - std::string FName; -}; -/**********************************************************************************************************************/ -/*@DEVI-struct for nullstmt*/ -struct NullStmtInfo -{ - NullStmtInfo (unsigned iColumn, unsigned iLine, std::string iFileName, bool iIsInMainFile, bool iIsInSysHeader) - { - Column = iColumn; - Line = iLine; - FileName = iFileName; - IsInMainFile = iIsInMainFile; - IsInSysHeader = iIsInSysHeader; - } - - unsigned Column; - unsigned Line; - std::string FileName; - bool IsInMainFile; - bool IsInSysHeader; -}; - -std::vector NullStmtProto; -/**********************************************************************************************************************/ -/*@DEVI-struct used for 8.8*/ -struct ExternObjInfo -{ - ExternObjInfo(unsigned int iLineNumber, unsigned int iColumnNumber, std::string iFileName\ - , std::string iXObjSLStr, std::string iXObjNameStr, FileID iXObjFID \ - , bool iHasMoreThanOneDefinition, bool iIsDefinition, bool iIsDeclaration) - { - LineNumber = iLineNumber; - ColumnNumber = iColumnNumber; - FileName = iFileName; - XObjSLStr = iXObjSLStr; - XObjNameStr = iXObjNameStr; - XObjFID = iXObjFID; - HasMoreThanOneDefinition = iHasMoreThanOneDefinition; - IsDefinition = iIsDefinition; - IsDeclaration = iIsDeclaration; - } - - unsigned int LineNumber; - unsigned int ColumnNumber; - std::string FileName; - std::string XObjSLStr; - std::string XObjNameStr; - FileID XObjFID; - bool HasMoreThanOneDefinition; - bool IsDefinition; - bool IsDeclaration; -}; - -std::vector ExternObjInfoProto; -/*@DEVI-end*/ -/**********************************************************************************************************************/ -/*@DEVI-struct used for rules 5.x*/ -struct IdentInfo -{ - IdentInfo(unsigned int iLine, unsigned int iColumn, std::string iFileName, std::string iName, \ - std::string iSLString, Devi::NodeKind iNK, bool iIsIncomplete, Devi::FunctionDeclKind IFDKind, \ - Devi::Scope iScope, std::string iScopeFuncitonName, bool iIsValid, bool iIsStatic) - { - Line = iLine; - Column = iColumn; - FileName = iFileName; - Name = iName; - SLString = iSLString; - NK = iNK; - IsIncomplete = iIsIncomplete; - FDKind = IFDKind; - Scope = iScope; - ScopeFunctionName = iScopeFuncitonName; - IsValid = iIsValid; - IsStatic = iIsStatic; - } - - unsigned int Line; - unsigned int Column; - std::string FileName; - std::string Name; - std::string SLString; - Devi::NodeKind NK; - bool IsIncomplete; - Devi::FunctionDeclKind FDKind; - Devi::Scope Scope; - std::string ScopeFunctionName; - bool IsValid; - bool IsStatic; -}; - -std::vector IdentInfoProto; - -std::unordered_map umRuleList; -/*@DEVI-end*/ -/**********************************************************************************************************************/ -/*mutator-lvl0 executable options*/ -enum MisraC -{ - NA=(0x1<<6), MisraC98=(0x1<<0), MisraC2004=(0x1<<2), MisraC2012=(0x1<<4), C1=(0x1<<1), C2=(0x1<<3), C3=(0x1<<5) -}; - -static llvm::cl::OptionCategory MutatorLVL0Cat("mutator-lvl0 options category"); -/*@DEVI-the option has been added since gcc does it.its as simple as that.*/ -cl::opt CheckSystemHeader("SysHeader", cl::desc("mutator-lvl0 will run through System Headers"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::ZeroOrMore); -cl::opt MainFileOnly("MainOnly", cl::desc("mutator-lvl0 will only report the results that reside in the main file"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::ZeroOrMore); -cl::opt MisraCVersion("MCV", cl::desc("choose the MisraC version to check against"), \ - cl::values(clEnumVal(MisraC98, "Misrac-1998"), clEnumVal(MisraC2004, "Misra-C:2004"), clEnumVal(MisraC2012, "Misra-C:2012"), \ - clEnumVal(C1, "Misra-C:1998"), clEnumVal(C2, "Misra-C:2004"), clEnumVal(C3, "Misra-C:2012")), cl::init(MisraC2004), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt MCE("MCE", cl::desc("MisraC switches to enable specific rule checks"), cl::init("10.1 "), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt MCD("MCD", cl::desc("MisraC switches to disable specific rule checks"), cl::init(" 9.3"), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt MCEA("MCEA", cl::desc("MisraC switch to enable all rule checks"), cl::init(true), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt MCDA("MCDA", cl::desc("MisraC switches to disable all rule checks"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt SFRCPP("SFRCPP", cl::desc("Enables SaferCPlusPlus rule checks"), cl::init(true), cl::cat(MutatorLVL0Cat), cl::Optional); -cl::opt mutagen("mutagen", cl::desc("runs mutagen after running the static tests"), cl::init(false), cl::cat(MutatorLVL0Cat), cl::Optional); -/**********************************************************************************************************************/ -class StringOptionsParser -{ -friend class MutatorLVL0Tests; - -public: - StringOptionsParser() {} - - bool MC2Parser(void) - { - if (MCDA) - { - PopulateRuleList(false); - } - else if (MCEA) - { - PopulateRuleList(true); - } - - ParseString(); - - UpdateRuleList(); - - return true; - } - - void Dump(bool InArg) - { - if (InArg) - { - for (auto &iter : umRuleList) - { - std::cout<< "Debug-umRuleList: " << "RLKey: " << iter.first << " " << "RLValue: " << iter.second << "\n"; - } - - std::cout << "\n"; - - for (auto &iter : ParsedString) - { - std::cout << "Debug: " << "PSKey: " << iter.first << " " << "PSValue: " << iter.second << "\n"; - } - } - } - -private: - void PopulateRuleList(bool PopValue) - { - if (MisraCVersion < 0x4) - { - // C1 - umRuleList.insert({"0", PopValue}); - - typedef std::multimap::const_iterator Iter; - for (Iter iter = MC1EquivalencyMap.begin(), iterE = MC1EquivalencyMap.end(); iter != iterE; ++iter) - { - if (iter->first != std::prev(iter)->first) - { - umRuleList.insert({iter->first, PopValue}); - } - } - } - - if (MisraCVersion < 0x10) - { - // C2 - typedef std::map::const_iterator Iter; - for (Iter iter = MC2OptsMap.begin(), iterE = MC2OptsMap.end(); iter != iterE; ++iter) - { - umRuleList.insert({iter->first, PopValue}); - } - - } - - if (MisraCVersion < 0x40) - { - // C3 - } - } - - void ParseString(void) - { -#if 0 - std::cout << "MCD:" << MCD << "\n"; - std::cout << "MCE:" << MCE << "\n"; -#endif - - bool Disenable; - std::string TempString; - - if (MCDA) - { - Disenable = true; - TempString = MCE; - } - else if (MCEA) - { - Disenable = false; - TempString = MCD; - } - - size_t WhiteSpacePos = TempString.find(" ", 0U); - size_t OldPosition = 0U; - - if (WhiteSpacePos == std::string::npos) - { - ParsedString.push_back(std::make_pair(TempString, false)); - - return void(); - } - - while(WhiteSpacePos != std::string::npos) - { - OldPosition = WhiteSpacePos; - WhiteSpacePos = TempString.find(" ", WhiteSpacePos + 1U); - - if (WhiteSpacePos != std::string::npos) - { - ParsedString.push_back(std::make_pair(TempString.substr(OldPosition + 1U, WhiteSpacePos - OldPosition - 1U), Disenable)); - } - } - } - - void UpdateRuleList(void) - { - for (auto &iter : umRuleList) - { - for (auto &yaiter : ParsedString) - { - if (iter.first == yaiter.first) - { - iter.second = yaiter.second; - break; - } - } - } - } - - std::vector> ParsedString; - - std::vector> RuleList [[deprecated("now using umRuleList")]]; -}; -/**********************************************************************************************************************/ -/**************************************************ASTMatcher Callbacks************************************************/ -class [[deprecated("replaced by a more efficient class"), maybe_unused]] MCForCmpless : public MatchFinder::MatchCallback { -public: - MCForCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfor") != nullptr) - { - const ForStmt *FS = MR.Nodes.getNodeAs("mcfor"); - - SourceLocation SL = FS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - -#if 0 - std::cout << "14.8 : " << "\"For\" statement has no braces {}: " << "\n"; - std::cout << SL.printToString(*MR.SourceManager) << "\n" << "\n"; -#endif - } - else - { - std::cout << "matcher -mcfor- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class [[deprecated("replaced by a more efficient class"), maybe_unused]] MCWhileCmpless : public MatchFinder::MatchCallback { -public: - MCWhileCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcwhile") != nullptr) - { - const WhileStmt *WS = MR.Nodes.getNodeAs("mcwhile"); - - SourceLocation SL = WS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - -#if 0 - std::cout << "14.8 : " << "\"While\" statement has no braces {}: " << "\n"; - std::cout << SL.printToString(*MR.SourceManager) << "\n" << "\n"; -#endif - } - else - { - std::cout << "matcher -mcwhile- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCElseCmpless : public MatchFinder::MatchCallback { -public: - MCElseCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcelse") != nullptr) - { - const IfStmt *IS = MR.Nodes.getNodeAs("mcelse"); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); - } - - SourceLocation SL = IS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.9:" << "\"Else\" statement has no braces {}:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.9", "\"Else\" statement has no braces {}: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.9", "\"Else\" statement has no braces {}: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcelse- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCIfCmpless : public MatchFinder::MatchCallback { -public: - MCIfCmpless (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcif") != nullptr) - { - const IfStmt *IS = MR.Nodes.getNodeAs("mcif"); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); - } - - SourceLocation SL = IS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.9:" << "\"If\" statement has no braces {}:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.9", "\"If\" statement has no braces {}: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.9", "\"If\" statement has no braces {}: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*IS), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcif- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class IfElseMissingFixer : public MatchFinder::MatchCallback -{ -public: - IfElseMissingFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcifelse") != nullptr) - { - const IfStmt *ElseIf = MR.Nodes.getNodeAs("mcifelse"); - - SourceLocation IFESL = ElseIf->getLocStart(); - CheckSLValidity(IFESL); - IFESL = Devi::SourceLocationHasMacro(IFESL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, IFESL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, IFESL)) - { - std::cout << "14.10:" << "\"If-Else If\" statement has no ending Else:"; - std::cout << IFESL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, IFESL, "14.10", "\"If-Else If\" statement has no ending Else: "); - JSONDocOUT.JSONAddElement(MR.Context, IFESL, "14.10", "\"If-Else If\" statement has no ending Else: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ElseIf), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcifelse- returned nullptr." << "\n"; - } - } - - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCSwitchBrkless : public MatchFinder::MatchCallback -{ -public: - MCSwitchBrkless (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcswitchbrk") != nullptr) - { - const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitchbrk"); - - SourceLocation SL = SS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "15.2:" << "\"SwitchStmt\" has a caseStmt that's missing a breakStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "15.2", "\"SwitchStmt\" has a caseStmt that's missing a breakStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "15.2", "\"SwitchStmt\" has a caseStmt that's missing a breakStmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcswitchbrk- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCSwitchDftLess : public MatchFinder::MatchCallback -{ -public: - MCSwitchDftLess (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcswitchdft") != nullptr) - { - const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitchdft"); - - SourceLocation SL = SS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "15.3:" << "\"SwitchStmt\" does not have a defaultStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "15.3", "\"SwitchStmt\" does not have a defaultStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "15.3", "\"SwitchStmt\" does not have a defaultStmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcswitchdft- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*misra-c 2004:15.1*/ -class MCSwitch151 : public MatchFinder::MatchCallback -{ -public: - MCSwitch151 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccmp151") != nullptr && MR.Nodes.getNodeAs("mccase151") != nullptr) - { - const CompoundStmt *CS = MR.Nodes.getNodeAs("mccmp151"); - const CaseStmt *SS = MR.Nodes.getNodeAs("mccase151"); - - SourceLocation SL = SS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - ASTContext *const ASTC = MR.Context; - - ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*CS); - - ast_type_traits::DynTypedNode ParentNode; - - /*@DEVI-assumptions:nothing has more than one parent in C.*/ - if (!NodeList.empty()) ParentNode = NodeList[0]; - else return void(); - - ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); - - std::string StringKind = ParentNodeKind.asStringRef().str(); - - if (StringKind != "SwitchStmt") - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "15.1:" << "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "15.1", "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "15.1", "\"CaseStmt\" has a CompoundStmt ancestor that is not the child of the SwitchStmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CS), *MR.Context); - } - } - } - } - else - { - std::cout << "matcher -mccmp151- or -mccase151- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCSwitch155 : public MatchFinder::MatchCallback -{ -public: - MCSwitch155 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcswitch155") != nullptr) - { - const SwitchStmt *SS = MR.Nodes.getNodeAs("mcswitch155"); - - SourceLocation SL = SS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "15.5:" << "\"SwitchStmt\" does not have a CaseStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "15.5", "\"SwitchStmt\" does not have a CaseStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "15.5", "\"SwitchStmt\" does not have a CaseStmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*SS), *MR.Context); - } - } - } - else - { - std::cout << "matcher -mcswitch155- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction161 : public MatchFinder::MatchCallback -{ -public: - MCFunction161 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunction161") != nullptr) - { - const FunctionDecl *FD = MR.Nodes.getNodeAs("mcfunction161"); - - if (FD->isVariadic()) - { - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "16.1:" << "\"FunctionDecl\" is variadic:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.1", "\"FunctionDecl\" is variadic: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.1", "\"FunctionDecl\" is variadic: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); - } - } - } - } - else - { - std::cout << "matcher -mcfunction161- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction162 : public MatchFinder::MatchCallback -{ -public: - MCFunction162 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mc162callexpr") != nullptr && MR.Nodes.getNodeAs("mc162funcdec") != nullptr) - { - const FunctionDecl *FD = MR.Nodes.getNodeAs("mc162funcdec"); - const CallExpr *CE = MR.Nodes.getNodeAs("mc162callexpr"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - return void(); - } - - - std::string FuncNameStr = FD->getNameInfo().getAsString(); - - if (CE->getDirectCallee()) - { - const FunctionDecl *FDCalled = CE->getDirectCallee(); - std::string CalledFuncNameStr = FDCalled->getNameInfo().getAsString(); - - if (FuncNameStr == CalledFuncNameStr) - { - std::cout << "16.2:" << "\"FunctionDecl\" is recursive:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.2", "\"FunctionDecl\" is recursive: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.2", "\"FunctionDecl\" is recursive: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CE), *MR.Context); - } - } - else - { - /*intentionally left blank.*/ - } - } - else - { - /*intentionally left blank.*/ - } - } - else - { - std::cout << "matcher -mc162funcdec- and/or -mc162callexpr- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction164 : public MatchFinder::MatchCallback -{ -public: - MCFunction164 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunc164") != nullptr) - { - const FunctionDecl *FD = MR.Nodes.getNodeAs("mcfunc164"); - const FunctionDecl *FDcl = FD->getDefinition(); - - /*to guard against function that have a declaration that is not a definition only.*/ - if (FDcl != nullptr) - { - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - return void(); - } - - SourceLocation SLDcl = FDcl->getLocStart(); - SLDcl = Devi::SourceLocationHasMacro(SLDcl, Rewrite, "start"); - - ArrayRef FDParmList = FD->parameters(); - - ArrayRef FDclParmList = FDcl->parameters(); - - if ( FD->getNumParams() != FDcl->getNumParams()) - { - std::cout << "numparam of functiondefinition and functionDecl dont match! : " << SL.printToString(*MR.SourceManager) << "\n" << "\n"; - } - else - { - if (FD->getNumParams() != 0) - { - for (unsigned x = 0; x < FD->getNumParams(); ++x) - { - if (FDParmList[x]->getNameAsString() != FDclParmList[x]->getNameAsString()) - { - std::cout << "16.4:" << "FunctionDecl parameter names are not the same as function definition parameter names:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.4", "FunctionDecl parameter names are not the same as function definition parameter names: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.4", "FunctionDecl parameter names are not the same as function definition parameter names: "); - - break; - } - else - { - /*intentionally left blank.*/ - } - } - } - } - } - } - else - { - std::cout << "matcher -mcfunc164- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction166 : public MatchFinder::MatchCallback -{ -public: - MCFunction166 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunc166") != nullptr) - { - const CallExpr *CE = MR.Nodes.getNodeAs("mcfunc166"); - - SourceLocation SL = CE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - const FunctionDecl *FD = CE->getDirectCallee(); - - DeclarationNameInfo DNI = FD->getNameInfo(); - - std::string FuncNameString = DNI.getAsString(); - - ASTContext *const ASTC = MR.Context; - - const SourceManager &SM = ASTC->getSourceManager(); - - /*start of 20.4*/ - if ((FuncNameString == "malloc" || FuncNameString == "calloc" || FuncNameString == "free" || FuncNameString == "realloc") && SM.isInSystemHeader(FD->getLocStart())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "20.4:" << "Dynamic heap memory allocation used:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "20.4", "Dynamic heap memory allocation used: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "20.4", "Dynamic heap memory allocation used: "); - - } - } - } - /*end of 20.4*/ - - /*start of 20.7*/ - if ((FuncNameString == "longjmp") && SM.isInSystemHeader(FD->getLocStart())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "20.7:" << "Use of lonjmp is illegal:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "20.7", "Use of longjmp is illegal: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "20.7", "Use of longjmp is illegal: "); - } - } - } - /*end of 20.7*/ - - /*start of 20.10*/ - if ((FuncNameString == "atof" || FuncNameString == "atoi" || FuncNameString == "atol") && SM.isInSystemHeader(FD->getLocStart())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "20.10:" << "Use of atof,atoi and atol is illegal:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "20.10", "Use of atof,atoi and atol is illegal: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "20.10", "Use of atof,atoi and atol is illegal: "); - } - } - } - /*end of 20.10*/ - - /*start of 20.11*/ - if ((FuncNameString == "abort" || FuncNameString == "exit" || FuncNameString == "getenv" || FuncNameString == "system") && SM.isInSystemHeader(FD->getLocStart())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "20.11:" << "Use of abort,exit,getenv and system is illegal:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "20.11", "Use of abort,exit,getenv and system is illegal : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "20.11", "Use of abort,exit,getenv and system is illegal : "); - } - } - } - /*end of 20.11*/ - - if (CE->getNumArgs() != FD->getNumParams()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "16.6:" << "CallExpr number of arguments does not equal the number of parameters in the declaration:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.6", "CallExpr number of arguments does not equal the number of parameters in the declaration: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.6", "CallExpr number of arguments does not equal the number of parameters in the declaration: "); - } - } - } - } - else - { - std::cout << "matcher -mcfunc166- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*the clang parser does not allow for such constructs.*/ -class [[maybe_unused]] MCFunction168 : public MatchFinder::MatchCallback -{ -public: - MCFunction168 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunc168") != nullptr) - { - const ReturnStmt *RT = MR.Nodes.getNodeAs("mcfunc168"); - - const Expr *RE [[maybe_unused]] = RT->getRetValue(); - - SourceLocation SL = RT->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - SourceLocation SLE = RT->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - - std::string RetType = Rewrite.getRewrittenText(SR); - -#if 0 - std::cout << RetType << "\n" << "\n"; -#endif - } - else - { - std::cout << "matcher -mcfunc168- returned nullptr." << "\n"; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction169 : public MatchFinder::MatchCallback -{ -public: - MCFunction169 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunc169") != nullptr) - { - const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("mcfunc169"); - - SourceLocation SL = ICE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - CastKind CK = ICE->getCastKind(); - - if (CK == CK_FunctionToPointerDecay) - { - std::cout << "16.9:" << "FunctionToPointerDecay:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.9", "FunctionToPointerDecay: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.9", "FunctionToPointerDecay: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-what is correct: match a pointer then run matcher for implicitcastexpressions of type arraytopointerdecay -that have unary(--,++) and binary(-,+) operators as parents*/ -class [[deprecated("replaced by something that actually works"), maybe_unused]] MCPA171 : public MatchFinder::MatchCallback -{ -public: - MCPA171 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcpa171") != nullptr) - { - const VarDecl *VD = MR.Nodes.getNodeAs("mcpa171"); - - QualType QT [[maybe_unused]] = VD->getType(); - -#if 0 - std::cout << QT.getAsString() << "\n" << "\n"; -#endif - } - } - -private: - Rewriter &Rewrite [[maybe_unused]]; -}; -/**********************************************************************************************************************/ -/*18.1 has false positives. incomplete types that have the same name as another incomplete -type in another scope are unrecognizable by this code.*/ -class MCSU184 : public MatchFinder::MatchCallback -{ -public: - MCSU184 (Rewriter &Rewrite) : Rewrite(Rewrite) - { - /*@DEVI-these push-backs generate garbage entries*/ - UnionInfoProto.push_back(UnionInfo()); - - StructInfoProto.push_back(StructInfo()); - - StructCounter = 0U; - UnionCounter = 0U; - } - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcsu184") != nullptr) - { - alreadymatched = false; - - const RecordDecl *RD = MR.Nodes.getNodeAs("mcsu184"); - - SourceLocation SL = RD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "18.4:" << "Union declared:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "18.4", "Union declared: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "18.4", "Union declared: "); - } - } - - std::string MatchedName = RD->getNameAsString(); - - for (unsigned x = 0; x < UnionCounter; ++x) - { - if (UnionInfoProto[x].UnionName == MatchedName) - { - alreadymatched = true; - - if (RD->isCompleteDefinition()) - { - UnionInfoProto[x].IsIncompleteType = false; - } - } - } - - if (alreadymatched == false) - { - UnionInfoProto.push_back(UnionInfo()); - UnionInfoProto[UnionCounter].UnionName = MatchedName; - UnionInfoProto[UnionCounter].UnionSL = SL.printToString(*MR.SourceManager); - UnionInfoProto[UnionCounter].FSL = FSL; - UnionInfoProto[UnionCounter].SL = SL; - - if (RD->isCompleteDefinition()) - { - /*this function has a declaration that is not a definition.*/ - UnionInfoProto[UnionCounter].IsIncompleteType = false; - } - - UnionCounter++; - } - } - - if (MR.Nodes.getNodeAs("mcsu181struct") != nullptr) - { - alreadymatched = false; - - const RecordDecl* RD = MR.Nodes.getNodeAs("mcsu181struct"); - - SourceLocation SL = RD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - std::string MatchedName = RD->getNameAsString(); - - for (unsigned x = 0; x < StructCounter; ++x) - { - if (StructInfoProto[x].StructName == MatchedName) - { - alreadymatched = true; - - if (RD->isCompleteDefinition()) - { - StructInfoProto[x].IsIncompleteType = false; - } - } - } - - if (alreadymatched == false) - { - StructInfoProto.push_back(StructInfo()); - StructInfoProto[StructCounter].StructName = MatchedName; - StructInfoProto[StructCounter].StructSL = SL.printToString(*MR.SourceManager); - StructInfoProto[StructCounter].FSL = FSL; - StructInfoProto[StructCounter].SL = SL; - - if (RD->isCompleteDefinition()) - { - StructInfoProto[StructCounter].IsIncompleteType = false; - } - - StructCounter++; - } - } - } - - virtual void onEndOfTranslationUnit() - { - for (unsigned x = 0; x < StructCounter; ++x) - { - if (StructInfoProto[x].IsIncompleteType) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, StructInfoProto[x].FSL.isInSystemHeader(), StructInfoProto[x].SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, StructInfoProto[x].FSL.getManager().isInMainFile(StructInfoProto[x].SL), StructInfoProto[x].SL)) - { - std::cout << "18.1:" << "Incomplete struct declared:"; - std::cout << StructInfoProto[x].StructSL << ":" << "\n"; - - XMLDocOut.XMLAddNode(StructInfoProto[x].FSL, StructInfoProto[x].SL, "18.1", "Incomplete struct declared: "); - JSONDocOUT.JSONAddElement(StructInfoProto[x].FSL, StructInfoProto[x].SL, "18.1", "Incomplete struct declared: "); - } - } - } - } - - for (unsigned x = 0; x < UnionCounter; ++x) - { - if (UnionInfoProto[x].IsIncompleteType) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, UnionInfoProto[x].FSL.isInSystemHeader(), UnionInfoProto[x].SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, UnionInfoProto[x].FSL.getManager().isInMainFile(UnionInfoProto[x].SL), UnionInfoProto[x].SL)) - { - std::cout << "18.1:" << "Incomplete union declared:"; - std::cout << UnionInfoProto[x].UnionSL << ":" << "\n"; - - XMLDocOut.XMLAddNode(UnionInfoProto[x].FSL, UnionInfoProto[x].SL, "18.1", "Incomplete union declared: "); - JSONDocOUT.JSONAddElement(UnionInfoProto[x].FSL, UnionInfoProto[x].SL, "18.1", "Incomplete union declared: "); - } - } - } - } - } - - -private: - struct UnionInfo - { - std::string UnionSL; - FullSourceLoc FSL; - SourceLocation SL; - std::string UnionName; - bool IsIncompleteType = true; - }; - - unsigned int UnionCounter; - - std::vector UnionInfoProto; - - struct StructInfo - { - std::string StructSL; - FullSourceLoc FSL; - SourceLocation SL; - std::string StructName; - bool IsIncompleteType = true; - }; - - unsigned StructCounter; - - bool alreadymatched = false; - - std::vector StructInfoProto; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCTypes6465 : public MatchFinder::MatchCallback -{ -public: - MCTypes6465 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mctype6465") != nullptr) - { - const FieldDecl *FD = MR.Nodes.getNodeAs("mctype6465"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QualType QT = FD->getType(); - const clang::Type* TP = QT.getTypePtr(); - - if ( !(TP->hasUnsignedIntegerRepresentation() || TP->hasSignedIntegerRepresentation())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*@DEVI-this part is ueless since the clang parser wont let such a bitfield through.*/ - std::cout << "6.4:" << "BitField has a type other than int or unsigned int:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.4", "BitField has a type other than int or unsigned int: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.4", "BitField has a type other than int or unsigned int: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); - } - } - } - } - - ASTContext *const ASTC = MR.Context; - unsigned int BitWidth = FD->getBitWidthValue(*ASTC); - - if (TP->hasSignedIntegerRepresentation()) - { - if (BitWidth < 2U) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "6.5:" << "BitField of type signed integer has a length of less than 2 in bits:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.5", "BitField of type signed integer has a length of less than 2 in bits : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.5", "BitField of type signed integer has a length of less than 2 in bits : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FD), *MR.Context); - } - } - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCDCDF81 : public MatchFinder::MatchCallback -{ -public: - MCDCDF81 (Rewriter &Rewrite) : Rewrite(Rewrite) - { - /*@DEVI-the pushback generates garbage entries.*/ - FuncInfoProto.push_back(FuncInfo()); - - VecC = 0U; - }; - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcdcdf81") != nullptr) - { - alreadymatched = false; - - const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf81"); - DeclarationNameInfo DNI = FD->getNameInfo(); - std::string MatchedName = DNI.getAsString(); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - SourceLocation SLE = FD->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - const SourceManager &SM = ASTC->getSourceManager(); - FullSourceLoc FSL = ASTC->getFullLoc(SL); - FullSourceLoc FSLE = ASTC->getFullLoc(SLE); - - /*start of 8.5*/ - bool FunctionDeclaredInsideHeader = false; - - if (FD->isThisDeclarationADefinition()) - { - for (unsigned x = 0; x < IncludeFileArr.size(); ++x) - { - if (SM.getFilename(SL).str() == IncludeFileArr[x]) - { - FunctionDeclaredInsideHeader = true; - } - } - } - - if (FunctionDeclaredInsideHeader) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "8.5:" << "Function definition inside a header file:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "8.5", "Function definition inside a header file : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "8.5", "Function definition inside a header file : "); - } - } - } - /*end of 8.5*/ - - - /*start of checks for 19.5*/ - /*has false positives. false positives go away if the main.c is not included(main.c includes another header)*/ - if (FD->isThisDeclarationADefinition()) - { - for (unsigned x = 0; x < MacroDefSourceLocation.size(); ++x) - { - if (FSL.isBeforeInTranslationUnitThan(MacroDefSourceLocation[x]) && \ - !FSLE.isBeforeInTranslationUnitThan(MacroDefSourceLocation[x]) && \ - SM.isInMainFile(MacroDefSourceLocation[x]) && !SM.isInSystemHeader(MacroDefSourceLocation[x])) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "19.5:" << "Macro defined inside a block:"; -#if 0 - std::cout << MacroDefSourceLocation[x].printToString(*MR.SourceManager) << " " << MacroNameString[x] << "\n" << "\n"; -#endif - std::cout << MacroDefSourceLocation[x].printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, MacroDefSourceLocation[x], "19.5", "Macro defined inside a block : "); - JSONDocOUT.JSONAddElement(MR.Context, MacroDefSourceLocation[x], "19.5", "Macro defined inside a block : "); - } - } - } - } - - for (unsigned x = 0; x < MacroUndefSourceLocation.size(); ++x) - { - if (FSL.isBeforeInTranslationUnitThan(MacroUndefSourceLocation[x]) && \ - !FSLE.isBeforeInTranslationUnitThan(MacroUndefSourceLocation[x]) && \ - SM.isInMainFile(MacroUndefSourceLocation[x]) && !SM.isInSystemHeader(MacroUndefSourceLocation[x])) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "19.5:" << "Macro undefined inside a block:"; - std::cout << MacroUndefSourceLocation[x].printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, MacroUndefSourceLocation[x], "19.5", "Macro undefined inside a block : "); - JSONDocOUT.JSONAddElement(MR.Context, MacroUndefSourceLocation[x], "19.5", "Macro undefined inside a block : "); - } - } - } - } - } - /*end of checks for 19.5*/ - - /*going through the already matched functions,making sure we are not adding duplicates.*/ - for (unsigned x = 0; x < VecC; ++x) - { - if (FuncInfoProto[x].FuncNameString == MatchedName) - { - alreadymatched = true; - - if (!FD->isThisDeclarationADefinition()) - { - FuncInfoProto[x].HasDecThatisNotDef = true; - } - } - } - - if (alreadymatched == false) - { - FuncInfoProto.push_back(FuncInfo()); - FuncInfoProto[VecC].FuncNameString = MatchedName; - - if (!FD->isThisDeclarationADefinition()) - { - /*this function has a declaration that is not a definition.*/ - FuncInfoProto[VecC].HasDecThatisNotDef = true; - } - else - { - /*save the sourcelocation only if the functiondecl is a definition.*/ - FuncInfoProto[VecC].StrcSL = SL.printToString(*MR.SourceManager); - FuncInfoProto[VecC].FuncSL = SL; - FuncInfoProto[VecC].FuncFSL = MR.Context->getFullLoc(SL); - } - - VecC++; - } - } - } - - virtual void onEndOfTranslationUnit() - { - - for (unsigned x = 0; x < VecC; ++x) - { - if (FuncInfoProto[x].HasDecThatisNotDef == false) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, FuncInfoProto[x].FuncFSL.isInSystemHeader(), FuncInfoProto[x].FuncSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, FuncInfoProto[x].FuncFSL.getManager().isInMainFile(FuncInfoProto[x].FuncSL), FuncInfoProto[x].FuncSL)) - { - std::cout << "8.1:" << "Function does not have a FunctionDecl that is not a definition:"; - std::cout << FuncInfoProto[x].StrcSL << ":" << "\n"; - - XMLDocOut.XMLAddNode(FuncInfoProto[x].FuncFSL, FuncInfoProto[x].FuncSL, "8.1", "Function does not have a FunctionDecl that is not a definition : "); - JSONDocOUT.JSONAddElement(FuncInfoProto[x].FuncFSL, FuncInfoProto[x].FuncSL, "8.1", "Function does not have a FunctionDecl that is not a definition : "); - } - } - } - } - - } - -private: - struct FuncInfo { - std::string FuncNameString; - std::string StrcSL; - bool HasDecThatisNotDef = false; - SourceLocation FuncSL; - FullSourceLoc FuncFSL; - }; - - std::vector FuncInfoProto; - - unsigned int VecC; - - bool alreadymatched = false; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*Notes:clang does not let 8.2 and 8.3 through.*/ -/*clang gives the implicitly-typed vardecl and functiondecl a default type in the AST so we cant use that. -we should just get the rewritten text and do string searches inside. thats the only way i can think of.*/ -class [[maybe_unused]] MCDCDF82 : public MatchFinder::MatchCallback -{ -public: - MCDCDF82 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcdcdf82") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf82"); - - std::string QualifiedName = VD->getQualifiedNameAsString(); - - QualType QT [[maybe_unused]] = VD->getType(); - -#if 0 - std::cout << QualifiedName << "\n" << "\n"; -#endif - } - } - -private: - Rewriter &Rewrite [[maybe_unused]]; -}; -/**********************************************************************************************************************/ -/*this class also matches aggregate types. a simple aggregate check should fix that, if need be.*/ -class MCInit91 : public MatchFinder::MatchCallback -{ -public: - MCInit91 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcinit91") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("mcinit91"); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SourceLocation SLMID; - - if (SL.isMacroID()) - { - SLMID = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - SourceLocation SLE = VD->getLocEnd(); - SourceLocation SLEMID; - - if (SLE.isMacroID()) - { - SLEMID = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - } - - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - QualType QT = VD->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - ASTContext *const ASTC = MR.Context; - - SourceManager &SM = ASTC->getSourceManager(); - - /*start of 8.5*/ - bool VarDeclaredInsideHeader = false; - - if (VD->isThisDeclarationADefinition(*ASTC) && !(!VD->isLocalVarDecl() && VD->isLocalVarDeclOrParm())) - { -#if 0 - std::cout << "XXXXXXXXXXXXXXXXXXXXXXXX" << " " << IncludeFileArr.size() << "\n"; -#endif - for (unsigned x = 0; x < IncludeFileArr.size(); ++x) - { - if (SM.getFilename(SL).str() == IncludeFileArr[x]) - { - VarDeclaredInsideHeader = true; - } - } - } - - if (VarDeclaredInsideHeader) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "8.5:" << "Variable definition inside a header file:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "8.5", "Variable definition inside a header file : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "8.5", "Variable definition inside a header file : "); - } - } - } - /*end of 8.5*/ - - /*start of 8.12*/ - if (!VD->hasInit()) - { - if (VD->hasExternalStorage()) - { - if (TP->isIncompleteArrayType()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*end of 8.12*/ - std::cout << "8.12:" << "External array type is incomplete and has no initialization:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "8.12", "External array type is incomplete and has no initialization : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "8.12", "External array type is incomplete and has no initialization : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*VD), *MR.Context); - } - } - } - } - } - } - /*start of 9.2*/ - else - { - if (TP->isArrayType() || TP->isStructureType()) - { - /*JANKY*/ - const Expr* InitExpr [[maybe_unused]] = VD->getInit(); - SourceRange InitExprSR; - SourceLocation IESL = InitExpr->getLocStart(); - CheckSLValidity(IESL); - IESL = Devi::SourceLocationHasMacro(IESL, Rewrite, "start"); - - CheckSLValidity(IESL); - - SourceLocation IESLE = InitExpr->getLocEnd(); - IESLE = Devi::SourceLocationHasMacro(IESLE, Rewrite, "end"); - InitExprSR.setBegin(IESL); - InitExprSR.setEnd(IESLE); - - std::string InitExprString = Rewrite.getRewrittenText(InitExprSR); - size_t openingcbraces = InitExprString.find("{", 0); - size_t closingcbraces = InitExprString.find("}", 0); - - if (openingcbraces == std::string::npos || closingcbraces == std::string::npos) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { -#if 0 - std::cout << "9.2:" << "Curly braces not used:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "9.2", "Curly braces not used : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "9.2", "Curly braces not used : "); -#endif - } - } - } - } - } - /*end of 9.2*/ - - /*we only check for local static since global static is meaningless.*/ - if (!VD->isStaticLocal() && VD->isLocalVarDecl()) - { - if (!VD->hasInit()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "9.1:" << "staic local variable does not have initialization:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "9.1", "staic local variable does not have initialization : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "9.1", "staic local variable does not have initialization : "); - } - } - } - } - } - - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class [[maybe_unused]] MCInit92 : public MatchFinder::MatchCallback -{ -public: - MCInit92 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcinit92") != nullptr) - { - const InitListExpr* ILE = MR.Nodes.getNodeAs("mcinit92"); - const VarDecl* VD = MR.Nodes.getNodeAs("mcinit92daddy"); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - unsigned int NumInits [[maybe_unused]] = ILE->getNumInits(); - -#if 0 - std::cout << NumInits << "\n" << "\n"; -#endif - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCInit93 : public MatchFinder::MatchCallback -{ -public: - MCInit93 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcinit93") != nullptr && MR.Nodes.getNodeAs("mcinit93daddy") != nullptr) - { - const EnumConstantDecl * ECD [[maybe_unused]] = MR.Nodes.getNodeAs("mcinit93"); - const EnumDecl* ED = MR.Nodes.getNodeAs("mcinit93daddy"); - /*do note that this pointer might very well be nullptr. we are actually counting on that. - it tells us we could not match an integer initialization for this enumconstantdecl.*/ - const IntegerLiteral* IL = MR.Nodes.getNodeAs("mcinit93kiddy"); - - SourceLocation SL = ED->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - newSourceLocation = SL; - - if (oldSourceLocation != newSourceLocation) - { - someoneHasInit = false; - everyoneHasInit = true; - isFirstElement = true; - if (IL == nullptr) - { - doesFirstElementHaveInit = false; - everyoneHasInit = false; - } - else - { - doesFirstElementHaveInit = true; - } - } - else - { - isFirstElement = false; - } - - if (oldSourceLocation == newSourceLocation) - { - if (IL == nullptr) - { - everyoneHasInit = false; - } - else - { - someoneHasInit = true; - } - - if (doesFirstElementHaveInit) - { - if (!everyoneHasInit && someoneHasInit) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*in breach of misrac*/ - std::cout << "9.3:" << "first enumeration has integerliteral initialization but not all enumerations do:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "9.3", "first enumeration has integerliteral initialization but not all enumerations do : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "9.3", "first enumeration has integerliteral initialization but not all enumerations do : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ECD), *MR.Context); - } - } - } - } - else - { - /*doesnt mean anything*/ - } - } - else - { - if (IL != nullptr) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - /*in breach of misrac*/ - std::cout << "9.3:" << "first enumeration does not have integerliteral initialization but at least one other enumeration does:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "9.3", "first enumeration does not have integerliteral initialization but at least one other enumeration does : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "9.3", "first enumeration does not have integerliteral initialization but at least one other enumeration does : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ECD), *MR.Context); - } - } - } - } - else - { - /*doesnt mean anything*/ - } - } - } - - oldSourceLocation = newSourceLocation; - } - } - -private: - /*doing this instead of saving everything and then running onendoftranslationunit is faster and less memory-expensive. - needless to say, for this to work, we are counting on clang's matching pattern.*/ - SourceLocation oldSourceLocation; - SourceLocation newSourceLocation; - - bool isFirstElement = false; - bool doesFirstElementHaveInit = false; - bool someoneHasInit = false; - bool everyoneHasInit = true; - - Rewriter &Rewrite; -}; - -/**********************************************************************************************************************/ -class MCExpr123 : public MatchFinder::MatchCallback -{ -public: - MCExpr123 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr123kiddy") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr123kiddy"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - ASTContext *const ASTC = MR.Context; - - if (EXP->HasSideEffects(*ASTC, true)) - { - std::cout << "12.3:" << "sizeof working on an expr with a side-effect:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.3", "sizeof working on an expr with a side-effect : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.3", "sizeof working on an expr with a side-effect : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr124 : public MatchFinder::MatchCallback -{ -public: - MCExpr124 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr124") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr124"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - ASTContext *const ASTC = MR.Context; - - if (EXP->HasSideEffects(*ASTC, true)) - { - std::cout << "12.4:" << "Righ-hand expr has side-effect:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.4", "Righ-hand expr has side-effect"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.4", "Righ-hand expr has side-effect"); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*DEVI-if all operands are boolean, this class will still tag em as inconsistent(with misrac).*/ -class MCExpr125 : public MatchFinder::MatchCallback -{ -public: - MCExpr125 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("lrhs") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("lrhs"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext *const ASTC [[maybe_unused]] = MR.Context; - - QualType QT [[maybe_unused]] = EXP->getType(); - - SourceLocation SLE = EXP->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - - std::string StrText = Rewrite.getRewrittenText(SR); - if (StrText[0] == '(' && StrText[StrText.length() - 1U] == ')') - { - hasParantheses = true; - } - else - { - hasParantheses = false; - } - - if (hasParantheses || SL.isMacroID()) - { - /*intentionally left blank.*/ - } - else - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "12.5:" << "RHS and/or LHS operands are not primary expressions:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.5", "RHS and/or LHS operands are not primary expressions : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.5", "RHS and/or LHS operands are not primary expressions : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - } - } - -private: - bool hasParantheses = false; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr126 : public MatchFinder::MatchCallback -{ -public: - MCExpr126 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr126rl") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr126rl"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - if (!EXP->isKnownToHaveBooleanValue()) - { - std::cout << "12.6:" << "RHS and/or LHS operands are not effectively-boolean values:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.6", "RHS and/or LHS operands are not effectively-boolean values : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.6", "RHS and/or LHS operands are not effectively-boolean values : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr127 : public MatchFinder::MatchCallback -{ -public: - MCExpr127 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr127rl") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr127rl"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType QT = EXP->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - if (TP->hasSignedIntegerRepresentation() && TP->isIntegerType()) - { - std::cout << "12.7:" << "Bitwise operator has signed RHS and/or LHS operands:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.7", "Bitwise operator has signed RHS and/or LHS operands: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.7", "Bitwise operator has signed RHS and/or LHS operands: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class [[maybe_unused]] MCExpr128 : public MatchFinder::MatchCallback -{ -public: - MCExpr128 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr128lhs") != nullptr && MR.Nodes.getNodeAs("mcexpr128rhs") != nullptr) - { - const Expr* RHS = MR.Nodes.getNodeAs("mcexpr128rhs"); - const Expr* LHS = MR.Nodes.getNodeAs("mcexpr128lhs"); - - SourceLocation SL = RHS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType RQT = RHS->getType(); - QualType LQT = LHS->getType(); - - ASTContext *const ASTC = MR.Context; - - const clang::Type* RTP [[maybe_unused]] = RQT.getTypePtr(); - const clang::Type* LTP = LQT.getTypePtr(); - - const clang::Type* CanonType = ASTC->getCanonicalType(LTP); - - uint64_t LHSSize = ASTC->getTypeSize(CanonType); - - llvm::APSInt Result; - - if (RHS->isIntegerConstantExpr(Result, *ASTC, nullptr, true)) - { - if ((Result >= (LHSSize - 1U)) || (Result <= 0)) - { - std::cout << "12.8:" << "shift size should be between zero and one less than the size of the LHS operand:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.8", "shift size should be between zero and one less than the size of the LHS operand: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.8", "shift size should be between zero and one less than the size of the LHS operand: "); - - /*@DEVI-FIXME-cant extract this one correctly*/ - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*RHS), *MR.Context); - } - } - } - - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr129 : public MatchFinder::MatchCallback -{ -public: - MCExpr129 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr129") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr129"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType QT = EXP->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - if (TP->isIntegerType() && TP->hasUnsignedIntegerRepresentation()) - { - std::cout << "12.9:" << "UnaryOperator - has an expr with an unsigned underlying type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.9", "UnaryOperator - has an expr with an unsigned underlying type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.9", "UnaryOperator - has an expr with an unsigned underlying type: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr1210 : public MatchFinder::MatchCallback -{ -public: - MCExpr1210 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr1210") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr1210"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "12.10:" << "Comma used:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.10", "Comma used: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.10", "Comma used: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr1213 : public MatchFinder::MatchCallback -{ -public: - MCExpr1213 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr1213") != nullptr) - { - const UnaryOperator* UO = MR.Nodes.getNodeAs("mcexpr1213"); - - SourceLocation SL = UO->getOperatorLoc(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "12.13:" << "Unary ++ or -- have been used in an expr with other operators:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.13", "Unary ++ or -- have been used in an expr with other operators: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.13", "Unary ++ or -- have been used in an expr with other operators: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*UO), *MR.Context); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE131 : public MatchFinder::MatchCallback -{ -public: - MCCSE131 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("cse131rlhs") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("cse131rlhs"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - if (EXP->isKnownToHaveBooleanValue()) - { - std::cout << "13.1:" << "assignment operator used in an expr that is known to return boolean:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.1", "assignment operator used in an expr that is known to return boolean: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.1", "assignment operator used in an expr that is known to return boolean: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE132 : public MatchFinder::MatchCallback -{ -public: - MCCSE132 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse132") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mccse132"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - if (!EXP->isKnownToHaveBooleanValue()) - { - std::cout << "13.2:" << "Implicit test of an expr against zero which is not known to return a boolean result:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.2", "Implicit test of an expr against zero which is not known to return a boolean result: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.2", "Implicit test of an expr against zero which is not known to return a boolean result: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE1332 : public MatchFinder::MatchCallback -{ -public: - MCCSE1332 (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse1332rl") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mccse1332rl"); - const BinaryOperator* BO = MR.Nodes.getNodeAs("mccse1332daddy"); - - SourceLocation SLD = BO->getLocStart(); - CheckSLValidity(SLD); - SLD = Devi::SourceLocationHasMacro(SLD, Rewrite, "start"); - NewSL = SLD; - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QualType QT = EXP->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - if (OldSL != NewSL) - { - if (TP->hasFloatingRepresentation()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "13.3:" << "Float type expression checked for equality/inequality:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.3", "Float type expression checked for equality/inequality: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.3", "Float type expression checked for equality/inequality: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - } - - OldSL = NewSL; - } - } - -private: - SourceLocation NewSL; - SourceLocation OldSL; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE134 : public MatchFinder::MatchCallback -{ -public: - MCCSE134 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse134") != nullptr) - { - AlreadyHaveAHit = false; - - const ForStmt* FS = MR.Nodes.getNodeAs("mccse134"); - - SourceLocation SL = FS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - const Expr* FSCond = FS->getCond(); - const Expr* FSInc = FS->getInc(); - -#if 0 - if (FSCond != nullptr) - { - std::string multix = Rewrite.getRewrittenText(FSCond->getSourceRange()); - std::cout << "diagnostic" << ":" << multix << "\n"; - } -#endif - - if (FSCond != nullptr) - { - QualType QTCond = FSCond->getType(); - - const clang::Type* TPCond = QTCond.getTypePtr(); - - if (TPCond->hasFloatingRepresentation()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "13.4:" << "Float type used in the controlling expression of a forstmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - AlreadyHaveAHit = true; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FS), *MR.Context); - } - } - } - } - } - - if (FSInc != nullptr && !AlreadyHaveAHit) - { - QualType QTInc = FSInc->getType(); - - const clang::Type* TPInc = QTInc.getTypePtr(); - - if (TPInc->hasFloatingRepresentation()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "13.4:" << "Float type used in the controlling expression of a forstmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - AlreadyHaveAHit = true; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.4", "Float type used in the controlling expression of a forstmt: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*FS), *MR.Context); - } - } - } - } - } - } - } - -private: - bool AlreadyHaveAHit = false; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*JANKY*/ -/*if a for controlling var is modified in the body using a pointer, then this class wont find it.*/ -/*the class will only work properly only if there is one controlling loop variable. -the behavior is undefined for more than one variable.*/ -class MCCSE136 : public MatchFinder::MatchCallback -{ -public: - MCCSE136 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse136kiddo") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mccse136kiddo"); - const ForStmt* FS = MR.Nodes.getNodeAs("mccse136daddy"); - - const Stmt* FSInit = FS->getInit(); - const Expr* FSInc = FS->getInc(); - const Expr* FSCond [[maybe_unused]] = FS->getCond(); - - /*underdev*/ - if (FSCond != nullptr) - { - SourceLocation CSL = FSCond->getLocStart(); - CheckSLValidity(CSL); - SourceLocation CSLE = FSCond->getLocEnd(); - SourceRange CSR; - CSR.setBegin(CSL); - CSR.setEnd(CSLE); - - std::string outstring = Rewrite.getRewrittenText(CSR); - -#if 0 - std::cout << "XXXXXXXXXXXXXXXXXXXXXX" << outstring << "\n"; -#endif - } - - - SourceLocation SLD = FS->getLocStart(); - CheckSLValidity(SLD); - SLD = Devi::SourceLocationHasMacro(SLD, Rewrite, "start"); - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (FSInit != nullptr && FSInc != nullptr) - { - SourceLocation SLFSInit = FSInit->getLocStart(); - SLFSInit = Devi::SourceLocationHasMacro(SLFSInit, Rewrite, "start"); - SourceLocation SLFSInc = FSInc->getLocStart(); - SLFSInc = Devi::SourceLocationHasMacro(SLFSInc, Rewrite, "start"); - - DeclarationNameInfo DNI = DRE->getNameInfo(); - - std::string NameString = DNI.getAsString(); - - /*JANKY*/ - /*@DEVI-the third condition is put in place to accomodate the prefix unary increment or decrement operator.*/ - if (SLFSInit == SL || SLFSInc == SL || SLFSInc.getLocWithOffset(2) == SL) - { - ControlVarName = NameString; - } - else - { - if (ControlVarName == NameString) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "13.6:" << "ForStmt controlling variable modified in the body of the loop:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.6", "ForStmt controlling variable modified in the body of the loop: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.6", "ForStmt controlling variable modified in the body of the loop: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); - } - } - } - } - } - - } - } - } - -private: - std::string ControlVarName; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF144 : public MatchFinder::MatchCallback -{ -public: - MCCF144 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccf144") != nullptr) - { - const GotoStmt* GS = MR.Nodes.getNodeAs("mccf144"); - - SourceLocation SL = GS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "14.4:" << "GotoStmt used:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.4", "GotoStmt used: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.4", "GotoStmt used: "); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF145 : public MatchFinder::MatchCallback -{ -public: - MCCF145 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccf145") != nullptr) - { - const ContinueStmt* CS = MR.Nodes.getNodeAs("mccf145"); - - SourceLocation SL = CS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "14.5:" << "ContinueStmt used:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.5", "ContinueStmt used: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.5", "ContinueStmt used: "); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF146 : public MatchFinder::MatchCallback -{ -public: - MCCF146 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccffofo") != nullptr) - { - const ForStmt* FS = MR.Nodes.getNodeAs("mccffofo"); - - SL = FS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - if (MR.Nodes.getNodeAs("mccfwuwu") != nullptr) - { - const WhileStmt* WS = MR.Nodes.getNodeAs("mccfwuwu"); - - SL = WS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - if (MR.Nodes.getNodeAs("mccfdodo") != nullptr) - { - const DoStmt* DS = MR.Nodes.getNodeAs("mccfdodo"); - - SL = DS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - NewSL = SL; - - if (OldSL != NewSL) - { - AlreadyTagged = false; - BreakCounter = 1U; - } - - if (OldSL == NewSL) - { - BreakCounter++; - } - - if (BreakCounter >= 2U && !AlreadyTagged) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.6:" << "More than one BreakStmt used in the loop counter:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - AlreadyTagged = true; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.6", "More than one BreakStmt used in the loop counter: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.6", "More than one BreakStmt used in the loop counter: "); - } - } - } - - OldSL = NewSL; - } - -private: - SourceLocation OldSL; - SourceLocation NewSL; - bool AlreadyTagged = false; - unsigned int BreakCounter = 0U; - SourceLocation SL; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF147 : public MatchFinder::MatchCallback -{ -public: - MCCF147 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccf147") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("mccf147"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - NewSL = SL; - - if (OldSL != NewSL) - { - AlreadyTagged = false; - ReturnCounter = 1U; - } - - if (OldSL == NewSL) - { - ReturnCounter++; - } - - if (ReturnCounter >= 2U && !AlreadyTagged) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.7:" << "More than one ReturnStmt used in the body of FunctionDecl:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - AlreadyTagged = true; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.7", "More than one ReturnStmt used in the body of FunctionDecl: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.7", "More than one ReturnStmt used in the body of FunctionDecl: "); - } - } - } - - OldSL = NewSL; - } - } - -private: - SourceLocation NewSL; - SourceLocation OldSL; - unsigned int ReturnCounter = 0U; - bool AlreadyTagged = false; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF148 : public MatchFinder::MatchCallback -{ -public: - MCCF148 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - - if (MR.Nodes.getNodeAs("mccf148for") != nullptr) - { - const ForStmt* FS = MR.Nodes.getNodeAs("mccf148for"); - - SL = FS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.8:" << "ForStmt does not have a child CompoundStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "ForStmt does not have a child CompoundStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "ForStmt does not have a child CompoundStmt: "); - } - } - } - - if (MR.Nodes.getNodeAs("mccf148while") != nullptr) - { - const WhileStmt* WS = MR.Nodes.getNodeAs("mccf148while"); - - SL = WS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.8:" << "WhileStmt does not have a child CompoundStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "WhileStmt does not have a child CompoundStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "WhileStmt does not have a child CompoundStmt: "); - } - } - } - - if (MR.Nodes.getNodeAs("mccf148do") != nullptr) - { - const DoStmt* DS = MR.Nodes.getNodeAs("mccf148do"); - - SL = DS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.8:" << "DoStmt does not have a child CompoundStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "DoStmt does not have a child CompoundStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "DoStmt does not have a child CompoundStmt: "); - } - } - } - - if (MR.Nodes.getNodeAs("mccf148switch") != nullptr) - { - const SwitchStmt* SS = MR.Nodes.getNodeAs("mccf148switch"); - - SL = SS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "14.8:" << "SwitchStmt does not have a child CompoundStmt:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "14.8", "SwitchStmt does not have a child CompoundStmt: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "14.8", "SwitchStmt does not have a child CompoundStmt: "); - } - } - } - } - -private: - SourceLocation SL; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCSwitch154 : public MatchFinder::MatchCallback\ -{ -public: - MCSwitch154 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcswitch154"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - if (EXP->isKnownToHaveBooleanValue()) - { - std::cout << "15.4:" << "Switch expression is effectively boolean:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "15.4", "Switch expression is effectively boolean: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "15.4", "Switch expression is effectively boolean: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-the current implementation of 11.3 is very strict.*/ -class MCPTC111 : public MatchFinder::MatchCallback -{ -public: - MCPTC111 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcptc111") != nullptr) - { - const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("mcptc111"); - - SourceLocation SL = ICE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QualType QT = ICE->getType(); - - const clang::Type* TP = QT.getTypePtr(); - -#if 0 - ASTContext *const ASTC = MR.Context; - - const ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*ICE); - - /*assumptions:implicitcastexpr does not have more than one parent in C.*/ - const ast_type_traits::DynTypedNode ParentNode = NodeList[0]; - - ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); - - std::string StringKind = ParentNodeKind.asStringRef().str(); - - const ImplicitCastExpr* ParentICE = ParentNode.get(); -#endif - - CastKind CK = ICE->getCastKind(); - - bool ShouldBeTagged111 = false; - - if (TP->isFunctionPointerType()) - { - if (((CK != CK_IntegralToPointer) && (CK != CK_PointerToIntegral) && \ - (CK != CK_LValueToRValue) && (CK != CK_FunctionToPointerDecay) && \ - (CK != CK_ArrayToPointerDecay))) - { - ShouldBeTagged111 = true; - } - - if (CK == CK_BitCast) - { - ShouldBeTagged111 = true; - } - - if (ShouldBeTagged111) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.1:" << "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.1", "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.1", "ImplicitCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); - } - } - } - } - } - - if (CK == CK_IntegralToFloating || CK == CK_FloatingToIntegral) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.1/2:" << "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr - Conversion of FloatingType to or from IntegralType is recommended against: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); - } - } - } - } - - if ((CK == CK_IntegralToPointer) || (CK == CK_PointerToIntegral)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.3:" << "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.3", "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.3", "ImplicitCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); - } - } - } - } - - if (CK == CK_BitCast || CK == CK_PointerToBoolean || CK == CK_AnyPointerToBlockPointerCast) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.x:" << "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.x", "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.x", "ImplicitCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*ICE), *MR.Context); - } - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE137 : public MatchFinder::MatchCallback -{ -public: - MCCSE137 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse137") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mccse137"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext *const ASTC = MR.Context; - - if (EXP->isKnownToHaveBooleanValue()) - { - if (EXP->isEvaluatable(*ASTC, Expr::SE_NoSideEffects)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "13.7:" << "EffectivelyBooleanExpr's result is known at compile-time:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.7", "EffectivelyBooleanExpr's result is known at compile-time: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.7", "EffectivelyBooleanExpr's result is known at compile-time: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - } - - QualType QT = EXP->getType(); - const clang::Type* TP = QT.getTypePtr(); - - if (TP->isIntegerType()) - { - ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*EXP); - - ast_type_traits::DynTypedNode ParentNode; - /*assumptions:nothing has more than one parent in C.*/ - if (!NodeList.empty()) ParentNode = NodeList[0]; - else return void(); - - ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); - - std::string StringKind = ParentNodeKind.asStringRef().str(); - - if (StringKind == "ImplicitCastExpr") - { - - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*if the call is coming from another file, getdirectcalle returns the definition, -but if its coming from the same file, it returns the declaration that is not a definition.*/ -/*if youve already matched the definition, getdefinition returns null.*/ -class MCDCDF810 : public MatchFinder::MatchCallback -{ -public: - MCDCDF810 (Rewriter &Rewrite) : Rewrite(Rewrite) - { - /*@DEVI-the pushback here generates garbage entries.*/ - FuncScopeProto.push_back(FuncScope()); - - VecC = 0U; - } - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcdcdf810") != nullptr && MR.Nodes.getNodeAs("mcdcdf810daddy") != nullptr) - { - AlreadyTagged = false; - - const CallExpr* CE = MR.Nodes.getNodeAs("mcdcdf810"); - const FunctionDecl* FDDad = MR.Nodes.getNodeAs("mcdcdf810daddy"); - const FunctionDecl* FD = CE->getDirectCallee(); - const FunctionDecl* FDDef = FD->getDefinition();; - - if (FDDef == nullptr) - { - FDDef = CE->getDirectCallee(); - } - - SourceLocation CESL = CE->getLocStart(); - CheckSLValidity(CESL); - CESL = Devi::SourceLocationHasMacro(CESL, Rewrite, "start"); - - SourceLocation FDDadSL = FDDad->getLocStart(); - CheckSLValidity(FDDadSL); - FDDadSL = Devi::SourceLocationHasMacro(FDDadSL, Rewrite, "start"); - - SourceLocation FDSL = FDDef->getLocStart(); - CheckSLValidity(FDSL); - FDSL = Devi::SourceLocationHasMacro(FDSL, Rewrite, "start"); - - ASTContext *const ASTC = MR.Context; - - FullSourceLoc FDDadFullSL = ASTC->getFullLoc(FDDadSL); - FullSourceLoc FDFullSL = ASTC->getFullLoc(FDSL); - - DeclarationNameInfo DNI = FDDef->getNameInfo(); - std::string MatchedName = DNI.getAsString(); - - /*going through the already matched functions,making sure we are not adding duplicates.*/ - for (unsigned x = 0; x < VecC; ++x) - { - if (FuncScopeProto[x].FuncNameString == MatchedName && FuncScopeProto[x].DefinitionSL == FDSL.printToString(*MR.SourceManager)) - { - AlreadyTagged = true; - - if (FDDef->isExternC()) - { - if (FDDadFullSL.getFileID() != FDFullSL.getFileID()) - { - FuncScopeProto[x].hasExternalCall = true; - } - } - } - } - - if (AlreadyTagged == false && FDDef->isExternC()) - { - FuncScopeProto.push_back(FuncScope()); - FuncScopeProto[VecC].FuncNameString = MatchedName; - FuncScopeProto[VecC].DefinitionSL = FDSL.printToString(*MR.SourceManager); - FuncScopeProto[VecC].FuncScopeSL = FDSL; - FuncScopeProto[VecC].FuncScopeFSL = MR.Context->getFullLoc(FDSL); - - if (FDDef->isExternC()) - { - if (FDDadFullSL.getFileID() != FDFullSL.getFileID()) - { - FuncScopeProto[VecC].hasExternalCall = true; - } - } - - VecC++; - } - } - } - - virtual void onEndOfTranslationUnit() - { - for (unsigned x = 0; x < VecC; ++x) - { - if (FuncScopeProto[x].hasExternalCall == false) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, FuncScopeProto[x].FuncScopeFSL.isInSystemHeader(), FuncScopeProto[x].FuncScopeSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, FuncScopeProto[x].FuncScopeFSL.getManager().isInMainFile(FuncScopeProto[x].FuncScopeSL), FuncScopeProto[x].FuncScopeSL)) - { - std::cout << "8.11:" << "Function does not have any external calls but is not declared as static:"; - std::cout << FuncScopeProto[x].DefinitionSL << ":" << "\n"; - - XMLDocOut.XMLAddNode(FuncScopeProto[x].FuncScopeFSL, FuncScopeProto[x].FuncScopeSL, "8.11", "Function does not have any external calls but is not declared as static : "); - JSONDocOUT.JSONAddElement(FuncScopeProto[x].FuncScopeFSL, FuncScopeProto[x].FuncScopeSL, "8.11", "Function does not have any external calls but is not declared as static : "); - } - } - } - } - } - -private: - struct FuncScope { - std::string FuncNameString; - bool hasExternalCall = false; - std::string DefinitionSL; - SourceLocation FuncScopeSL; - FullSourceLoc FuncScopeFSL; - }; - - bool AlreadyTagged = false; - - unsigned VecC; - - std::vector FuncScopeProto; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-also flags the main.*/ -class MCFunction165 : public MatchFinder::MatchCallback -{ -public: - MCFunction165 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunction165") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("mcfunction165"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "16.5:" << "Function does not return anything but is missing the void keyword for the return type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.5", "Function does not return anything but is missing the void keyword for the return type : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.5", "Function does not return anything but is missing the void keyword for the return type : "); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCFunction1652 : public MatchFinder::MatchCallback -{ -public: - MCFunction1652 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunction1652") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("mcfunction1652"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SourceLocation SLE = FD->getBody()->getLocStart(); - CheckSLValidity(SLE); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - - std::string FunctionSigAsString = Rewrite.getRewrittenText(SR); - - DeclarationNameInfo DNI = FD->getNameInfo(); - - std::string NameAsString = DNI.getAsString(); - - size_t voidposition = FunctionSigAsString.find(NameAsString, 0U); - unsigned lengthofstring = NameAsString.length(); - size_t voidposition2 = FunctionSigAsString.find("void", voidposition + lengthofstring - 1U); - - if (voidposition2 == std::string::npos) - { - std::cout << "16.5:" << "Function does not take any parameters but is not using the void keyword:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.5", "Function does not take any parameters but is not using the void keyword : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.5", "Function does not take any parameters but is not using the void keyword : "); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-has false-positives*/ -class MCPointer171 : public MatchFinder::MatchCallback -{ -public: - MCPointer171 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcpointer171") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mcpointer171") ; - - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType QT = DRE->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - if (TP->isAnyPointerType()) - { - std::cout << "17.1:" << "Pointer arithmatic for non-array pointers:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "17.1", "Pointer arithmatic for non-array pointers : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "17.1", "Pointer arithmatic for non-array pointers : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-has a lot of false positives. now works based on array types not the array itself.*/ -class MCPointer1723 : public MatchFinder::MatchCallback -{ -public: - MCPointer1723 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcpointer1723rhs") != nullptr && MR.Nodes.getNodeAs("mcpointer1723lhs")) - { - const DeclRefExpr* DRER = MR.Nodes.getNodeAs("mcpointer1723rhs"); - const DeclRefExpr* DREL = MR.Nodes.getNodeAs("mcpointer1723lhs"); - const BinaryOperator* BO = MR.Nodes.getNodeAs("mcpointer1723daddy"); - - SourceLocation SL = BO->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType QTR = DRER->getType(); - QualType QTL = DREL->getType(); - - const clang::Type* TPR = QTR.getTypePtr(); - const clang::Type* TPL = QTL.getTypePtr(); - - if (TPR->getPointeeType() != TPL->getPointeeType()) - { - std::cout << "17.2 | 17.3:" << "Pointer-type operands to BinaryOperator dont point to the same array:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "17.2 | 17.3", "Pointer-type operands to BinaryOperator dont point to the same array : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "17.2 | 17.3", "Pointer-type operands to BinaryOperator dont point to the same array : "); - - /*@DEVI-FIXME-cant extract mutagen correctly*/ - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*BO), *MR.Context); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCPointer174 : public MatchFinder::MatchCallback -{ -public: - MCPointer174 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcpointer174") != nullptr) - { - const CastExpr* CE = MR.Nodes.getNodeAs("mcpointer174"); - - SourceLocation SL = CE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "17.4:" << "The only allowed form of pointer arithmetic is array indexing:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CE), *MR.Context); - } - } - } - } - - if (MR.Nodes.getNodeAs("mcpointer1742") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("mcpointer1742"); - - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "17.4:" << "The only allowed form of pointer arithmetic is array indexing:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "17.4", "The only allowed form of pointer arithmetic is array indexing : "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*DRE), *MR.Context); - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-in case of function pointers, where an argument has more than two levels of indirection, -the argument and the function pointer both get tagged. technically, it is a defendable interpretation of the rule.*/ -class MCPointer175 : public MatchFinder::MatchCallback -{ -public: - MCPointer175 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - const VarDecl* VD; - const FieldDecl* FD; - SourceLocation SL; - QualType QT; - - if (MR.Nodes.getNodeAs("mcpointer175") != nullptr) - { - VD = MR.Nodes.getNodeAs("mcpointer175"); - - SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QT = VD->getType(); - } - - if (MR.Nodes.getNodeAs("mcpointer175field") != nullptr) - { - FD = MR.Nodes.getNodeAs("mcpointer175field"); - - SL = FD->getSourceRange().getBegin(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QT = FD->getType(); - } - - - QualType CQT = QT.getCanonicalType(); - - std::string CQTAsString = CQT.getAsString(); - - const clang::Type* TP [[maybe_unused]] = CQT.getTypePtr(); - - unsigned starCounter = 0U; - size_t StarPos = 0U; - size_t OpenParens = 0U; - size_t NextOpenParens = 0U; - size_t CommaPos = 0U; - size_t NextCommaPos = 0U; - bool FoundAMatch [[maybe_unused]] = false; - - while (StarPos != std::string::npos) - { - StarPos = CQTAsString.find("*", StarPos + 1); - OpenParens = CQTAsString.find("(", NextOpenParens + 1); - CommaPos = CQTAsString.find(",", NextCommaPos + 1); - - if (OpenParens != std::string::npos) - { - if (StarPos > OpenParens) - { - starCounter = 0U; - NextOpenParens = OpenParens; - } - - } - - if (CommaPos != std::string::npos) - { - if (StarPos > CommaPos) - { - starCounter = 0U; - NextCommaPos = CommaPos; - } - } - - if (StarPos != std::string::npos) - { - starCounter++; - } - - if (starCounter >= 3U) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "17.5:" << "Pointer has more than 2 levels of indirection:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "17.5", "Pointer has more than 2 levels on indirection : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "17.5", "Pointer has more than 2 levels on indirection : "); - } - } - - break; - } - } - - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-the simple char type can be singed or unsigned. its implementation-defined. the values appear -folded on AST and currently i dont know of a method to differentiate between singed/unsigned char and simple char. -sure, we can get the text of the vardecl and do string search in there but that still does not solve our problem. -we could do string search for the RHS expression but thats limited and then there is flagging cases that are of char -type because of a macro expansion(the macro adding signed or unsinged to the char type). we could flag those macros -in a PPCallback::MacroDefined but that leaves us with the problem of CStyleCasts. for example when a -simple char type is assigned a numeric values cast explicitly cast to simple char, misra-c says it does not -break rule 6.1(see https://www.misra.org.uk/forum/viewtopic.php?t=1020 for reference). the bottom line is, -there is a way to implement this but the implementation will be janky and its too much trouble for a janky -implementation that later on will not be modifiable much.*/ -class MCTypes61 : public MatchFinder::MatchCallback -{ -public: - MCTypes61 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if ((MR.Nodes.getNodeAs("mctypes6rhs") != nullptr) \ - && (MR.Nodes.getNodeAs("mctypes6origin") != nullptr) \ - && (MR.Nodes.getNodeAs("mctypes6dous") != nullptr)) - { - const Expr* EXP = MR.Nodes.getNodeAs("mctypes6rhs"); - const VarDecl* VD = MR.Nodes.getNodeAs("mctypes6origin"); - - QualType QT = VD->getType(); - const clang::Type* TP = QT.getTypePtr(); - - QualType QTEXP = EXP->getType(); - const clang::Type* TPEXP = QTEXP.getTypePtr(); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SourceLocation SLE = EXP->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - -#if 0 - std::string RHSString = Rewrite.getRewrittenText(SR); - - //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << "\n"; - - size_t singleQuoteLoc = RHSString.find("'", 0U); - size_t doubleQuoteLoc = RHSString.find("\"", 0U); - size_t singleQuoteLocE = RHSString.rfind("'", 0U); - size_t doubleQuoteLocE = RHSString.rfind("\"", 0U); -#endif - - /*@DEVI-the logic here is that we know we have matched a chartype. if its not either a singedinteger or - unsingedinteger, then it is a simple char. otherwise it is signed or unsigned char.*/ -#if 1 - if (TP->isSignedIntegerType() || TP->isUnsignedIntegerType()) - { - //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << SL.printToString(*MR.SourceManager) << "\n"; - - if (!TPEXP->isSignedIntegerType() && !TPEXP->isUnsignedIntegerType()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "6.2:" << "Sgined or unsigned char type holds characterLiterals:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.2", "Sgined or unsigned char type holds characterLiterals : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.2", "Sgined or unsigned char type holds characterLiterals : "); - } - } - } - } - else - { - - } - - if (!TP->isSignedIntegerType() && !TP->isUnsignedIntegerType()) - { - //std::cout << RHSString << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << SL.printToString(*MR.SourceManager) << "\n"; - - if (TPEXP->isSignedIntegerType() || TPEXP->isUnsignedIntegerType()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "6.1:" << "Simple char type holds numeric values:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.1", "Simple char type holds numeric values : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.1", "Simple char type holds numeric values : "); - } - } - } - } -#endif - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCSU181 : public MatchFinder::MatchCallback -{ -public: - MCSU181 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcsu181arr") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("mcsu181arr"); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "18.1:" << "ArrayType incomplete at the end of the translation unit:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "18.1", "ArrayType incomplete at the end of the translation unit : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "18.1", "ArrayType incomplete at the end of the translation unit : "); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCPTC11CSTYLE : public MatchFinder::MatchCallback -{ -public: - MCPTC11CSTYLE (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcptc11cstyle") != nullptr) - { - const CStyleCastExpr* CSCE = MR.Nodes.getNodeAs("mcptc11cstyle"); - - SourceLocation SL = CSCE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - QualType QT = CSCE->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - ASTContext *const ASTC [[maybe_unused]] = MR.Context; - -#if 0 - const ASTContext::DynTypedNodeList NodeList = ASTC->getParents(*CSCE); - - /*assumptions:implicitcastexpr does not have more than one parent in C.*/ - const ast_type_traits::DynTypedNode ParentNode = NodeList[0]; - - ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); - - std::string StringKind = ParentNodeKind.asStringRef().str(); -#endif - - CastKind CK = CSCE->getCastKind(); - - bool ShouldBeTagged11 = false; - - if (TP->isFunctionPointerType()) - { - if (((CK != CK_IntegralToPointer) && (CK != CK_PointerToIntegral) && \ - (CK != CK_LValueToRValue) && (CK != CK_FunctionToPointerDecay) && \ - (CK != CK_ArrayToPointerDecay))) - { - ShouldBeTagged11 = true; - } - - if (CK == CK_BitCast) - { - ShouldBeTagged11 = true; - } - - if (ShouldBeTagged11) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.1:" << "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.1", "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.1", "CStyleCastExpr - FunctionPointerType converted to or from a type other than IntegralType: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); - } - } - } - } - } - - if ((CK == CK_IntegralToPointer) || (CK == CK_PointerToIntegral)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.3:" << "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.3", "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.3", "CStyleCastExpr - Conversion of PointerType to or from IntegralType is recommended against: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); - } - } - } - } - - if (CK == CK_BitCast || CK == CK_PointerToBoolean || CK == CK_AnyPointerToBlockPointerCast) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "11.x:" << "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "11.x", "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "11.x", "CStyleCastExpr - PointerType has implicit BitCast. This could be caused by a cast removing const or volatile qualifier from the type addressed by a pointer or by a cast to a different function or object type: "); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*CSCE), *MR.Context); - } - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCATC101 : public MatchFinder::MatchCallback -{ -public: - MCATC101 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("atcdaddy") != nullptr) - { - const ImplicitCastExpr* ICE = MR.Nodes.getNodeAs("atcdaddy"); - - if ((ICE->getCastKind() == CK_IntegralCast) || (ICE->getCastKind() == CK_FloatingCast) || \ - (ICE->getCastKind() == CK_FloatingComplexCast) || (ICE->getCastKind() == CK_IntegralComplexCast)) - { - SourceLocation SL = ICE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext *const ASTC = MR.Context; - - QualType QTDaddy = ICE->getType(); - QualType QTKiddy; - - if (MR.Nodes.getNodeAs("atcdous") != nullptr) - { - const BinaryOperator* ChildNode = MR.Nodes.getNodeAs("atcdous"); - QTKiddy = ChildNode->getType(); - } - - if (MR.Nodes.getNodeAs("atcuno") != nullptr) - { - const UnaryOperator* ChildNode = MR.Nodes.getNodeAs("atcuno"); - QTKiddy = ChildNode->getType(); - } - - if (MR.Nodes.getNodeAs("atcparens") != nullptr) - { - const ParenExpr* ChildNode = MR.Nodes.getNodeAs("atcparens"); - QTKiddy = ChildNode->getType(); - } - - if (MR.Nodes.getNodeAs("atckidice") != nullptr) - { - const ImplicitCastExpr* ChildNode = MR.Nodes.getNodeAs("atckidice"); - QTKiddy = ChildNode->getType(); - } - - if (MR.Nodes.getNodeAs("atccstyle") != nullptr) - { - const CStyleCastExpr* ChildNode = MR.Nodes.getNodeAs("atccstyle"); - QTKiddy = ChildNode->getType(); - } - - const clang::Type* TPDaddy = QTDaddy.getTypePtr(); - const clang::Type* TPChild = QTKiddy.getTypePtr(); - - const clang::Type* CanonTypeDaddy = ASTC->getCanonicalType(TPDaddy); - const clang::Type* CanonTypeChild = ASTC->getCanonicalType(TPChild); - - uint64_t ICETypeSize = ASTC->getTypeSize(CanonTypeDaddy); - uint64_t ChildTypeSize = ASTC->getTypeSize(CanonTypeChild); - - bool ICETypeIsSignedInt = CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Long) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Short) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::SChar) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_S) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::LongLong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int128) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_S); - bool ChildTypeIsSignedInt = CanonTypeChild->isSpecificBuiltinType(BuiltinType::Kind::Long) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Short) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::SChar) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_S) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::LongLong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Int128) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_S); - - bool ICETypeIsUSignedInt = CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); - bool ChildTypeIsUSignedInt = CanonTypeChild->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ - CanonTypeDaddy->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); - - bool ICETypeIsInteger = ICETypeIsSignedInt || ICETypeIsUSignedInt; - bool ChildTypeIsInteger = ChildTypeIsSignedInt || ChildTypeIsUSignedInt; - - if (ICETypeIsInteger && ChildTypeIsInteger) - { - if ((ICETypeIsSignedInt && ChildTypeIsUSignedInt) || (ICETypeIsUSignedInt && ChildTypeIsSignedInt)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.1/2:" << "ImplicitCastExpr changes the signedness of the type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr changes the signedness of the type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr changes the signedness of the type: "); - } - } - } - } - - if (ICETypeSize < ChildTypeSize && !(CanonTypeChild->isComplexIntegerType() || CanonTypeChild->isComplexType())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.1/2:" << "ImplicitCastExpr is narrowing:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.1/2", "ImplicitCastExpr is narrowing: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.1/2", "ImplicitCastExpr is narrowing: "); - } - } - } - - if (CanonTypeChild->isComplexIntegerType()) - { - if (ICETypeSize > ChildTypeSize) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.3:" << "ImplicitCastExpr is widening for complex integer type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.3", "ImplicitCastExpr is widening for complex integer type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.3", "ImplicitCastExpr is widening for complex integer type: "); - } - } - } - - const ComplexType* ChildCPXType = CanonTypeChild->getAsComplexIntegerType(); - const ComplexType* DaddyCPXType = CanonTypeDaddy->getAsComplexIntegerType(); - - QualType DaddyCPXQT = DaddyCPXType->getElementType(); - QualType ChildCPXQT = ChildCPXType->getElementType(); - - const clang::Type* DaddyCPXElementType = DaddyCPXQT.getTypePtr(); - const clang::Type * ChildCPXElementType = ChildCPXQT.getTypePtr(); - - /* - bool IsSignedCPXDaddy = DaddyCPXElementType->getAsPlaceholderType()->isSignedInteger(); - bool IsSignedCPXChild = ChildCPXElementType->getAsPlaceholderType()->isSignedInteger(); - bool IsUnsignedCPXDaddy = DaddyCPXElementType->getAsPlaceholderType()->isUnsignedInteger(); - bool IsUnsignedCPXChild = ChildCPXElementType->getAsPlaceholderType()->isUnsignedInteger(); - */ - - bool IsSignedCPXDaddy = false; - bool IsUnsignedCPXDaddy = false; - if (DaddyCPXElementType) { - auto placeholderType = DaddyCPXElementType->getAsPlaceholderType(); - if (placeholderType) { - IsSignedCPXDaddy = placeholderType->isSignedInteger(); - IsUnsignedCPXDaddy = placeholderType->isUnsignedInteger(); - } - } - - bool IsSignedCPXChild = false; - bool IsUnsignedCPXChild = false; - if (ChildCPXElementType) { - auto placeholderType = ChildCPXElementType->getAsPlaceholderType(); - if (placeholderType) { - IsSignedCPXChild = placeholderType->isSignedInteger(); - IsUnsignedCPXChild = placeholderType->isUnsignedInteger(); - } - } - - if ((IsSignedCPXDaddy && IsUnsignedCPXChild) || (IsUnsignedCPXDaddy && IsSignedCPXChild)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.3:" << "ImplicitCastExpr changes the signedness of the complex integer type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.3", "ImplicitCastExpr changes the signedness of the complex integer type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.3", "ImplicitCastExpr changes the signedness of the complex integer type type: "); - } - } - } - } - - /*clang::Type::iSComplexIntegerType will not return true for the gnu extension of complex integers.*/ - if (!CanonTypeChild->isComplexIntegerType() && CanonTypeChild->isComplexType()) - { - if (ICETypeSize > ChildTypeSize) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "10.4:" << "ImplicitCastExpr is widening for complex float type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.4", "ImplicitCastExpr is widening for complex float type: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.4", "ImplicitCastExpr is widening for complex float type: "); - } - } - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCIdent51 : public MatchFinder::MatchCallback -{ -public: - MCIdent51 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("ident5nameddecl") != nullptr) - { - const NamedDecl* ND = MR.Nodes.getNodeAs("ident5nameddecl"); - - const IdentifierInfo *II = ND->getIdentifier(); - - SourceLocation SL = ND->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext *const ASTC = MR.Context; - - const IdentifierTable &IT = ASTC->Idents; - - if (II != nullptr) - { - StringRef IdentStringRef = II->getName(); - - for (auto &iter : IT) - { - /*@DEVI-only works for UTF-8. for larger sizes we need a multiple of 32. for UTF-16 we need to check against 64 and so on.*/ - if (IdentStringRef.str().size() >= 32U) - { - if ((iter.getValue()->getName().str().substr(0U, 32U) == IdentStringRef.str().substr(0U, 32U)) && (iter.getValue()->getName().str() != IdentStringRef.str())) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "5.1:" << "Identifier relies on the signifacance of more than 31 charcaters:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "5.1", "Identifier relies on the significance of more than 31 charcaters: "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "5.1", "Identifier relies on the significance of more than 31 charcaters: "); - } - } - } - } - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCDCDF87 : public MatchFinder::MatchCallback -{ -public: - MCDCDF87 (Rewriter &Rewrite) : Rewrite(Rewrite) - { - IsNewEntry = true; - } - - virtual void run(const MatchFinder::MatchResult &MR) - { - if ((MR.Nodes.getNodeAs("mcdcdfobj") != nullptr) \ - && (MR.Nodes.getNodeAs("mcdcdf87daddy") != nullptr) && \ - (MR.Nodes.getNodeAs("mcdcdf87origin") != nullptr)) - { - IsNewEntry = true; - - const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf87daddy"); - const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf87origin"); - - std::string VDName = VD->getIdentifier()->getName().str(); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - - for (auto &iter : MaybeLocalObjInfoProto) - { - if (iter.ObjNameStr == VDName && iter.ObjSL == SL) - { - IsNewEntry = false; - - if ((iter.FirstDaddyName != FD->getNameInfo().getAsString())) - { - iter.HasMoreThanOneDaddy = true; - } - } - } - - if (IsNewEntry) - { - MaybeLocalObjInfo Temp = {SL, ASTC->getFullLoc(SL), SL.printToString(*MR.SourceManager), VDName, FD->getNameInfo().getAsString(), false}; - MaybeLocalObjInfoProto.push_back(Temp); - } - } - } - - virtual void onEndOfTranslationUnit() - { - for (auto &iter : MaybeLocalObjInfoProto) - { - if (!iter.HasMoreThanOneDaddy) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, iter.ObjFSL.isInSystemHeader(), iter.ObjSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, iter.ObjFSL.getManager().isInMainFile(iter.ObjSL), iter.ObjSL)) - { - std::cout << "8.7:" << "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block:"; - std::cout << iter.ObjSLStr << ":" << "\n"; - - XMLDocOut.XMLAddNode(iter.ObjFSL, iter.ObjSL, "8.7", \ - "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block: "); - JSONDocOUT.JSONAddElement(iter.ObjFSL, iter.ObjSL, "8.7", \ - "Object (" + iter.ObjNameStr + ") is only being used in one block (" + iter.FirstDaddyName + ") but is not defined inside that block: "); - } - } - } - } - } - - -private: - struct MaybeLocalObjInfo - { - MaybeLocalObjInfo(SourceLocation iObjSL, FullSourceLoc iObjFSL, std::string iObjSLStr, \ - std::string iObjNameStr, std::string iFirstDaddyName, bool iHasMoreThanOneDaddy = false) - { - ObjSL = iObjSL; - ObjFSL = iObjFSL; - ObjSLStr = iObjSLStr; - ObjNameStr = iObjNameStr; - FirstDaddyName = iFirstDaddyName; - HasMoreThanOneDaddy = iHasMoreThanOneDaddy; - } - - SourceLocation ObjSL; - FullSourceLoc ObjFSL; - std::string ObjSLStr; - std::string ObjNameStr; - std::string FirstDaddyName; - bool HasMoreThanOneDaddy = false; - }; - - bool IsNewEntry; - - std::vector MaybeLocalObjInfoProto; - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-has false positives will tag incomplete types if they are later declared as complete types.*/ -class [[maybe_unused]] MCDCDF88 : public MatchFinder::MatchCallback -{ -public: - MCDCDF88 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - bool IsNewEntry = true; - - if (MR.Nodes.getNodeAs("mcdcdf88var") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("mcdcdf88var"); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - const SourceManager &SM = FSL.getManager(); - - if (!SM.isInMainFile(SL)) - { - return void(); - } - - std::string NDNameString = VD->getNameAsString(); - - for (auto &iter : ExternObjInfoProto) - { -#if 0 - std::cout << "diagnostic2:" << "Variable:" << NDNameString << ":" << iter.XObjNameStr << "\n"; -#endif - if (iter.XObjNameStr == NDNameString) - { - IsNewEntry = false; - - iter.HasMoreThanOneDefinition = true; - } - } - - if (IsNewEntry) - { - const SourceManager &SM = FSL.getManager(); - - ExternObjInfo Temp = {FSL.getSpellingLineNumber(), FSL.getSpellingColumnNumber(), \ - SM.getFilename(SL), SL.printToString(*MR.SourceManager), NDNameString, \ - FSL.getFileID(), false, false, false - }; - ExternObjInfoProto.push_back(Temp); - } - } - - if (MR.Nodes.getNodeAs("mcdcdf88function") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("mcdcdf88function"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext* const ASTC = MR.Context; - - std::string NDNameString = FD->getNameAsString(); - - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - const SourceManager &SM = FSL.getManager(); - - if (!SM.isInMainFile(SL)) - { - return void(); - } - - for (auto &iter : ExternObjInfoProto) - { - if (iter.XObjNameStr == NDNameString) - { - IsNewEntry = false; - - - if ((iter.IsDefinition == true && FD->isThisDeclarationADefinition()) || (iter.IsDeclaration == true && !FD->isThisDeclarationADefinition())) - { - iter.HasMoreThanOneDefinition = true; - - if (FD->isThisDeclarationADefinition()) - { - iter.IsDefinition = true; - } - else - { - iter.IsDeclaration = true; - } - } - - } - } - - if (IsNewEntry) - { - ExternObjInfo Temp = {FSL.getSpellingLineNumber(), FSL.getSpellingColumnNumber(), \ - SM.getFilename(SL), SL.printToString(*MR.SourceManager), NDNameString, \ - FSL.getFileID(), false, FD->isThisDeclarationADefinition(), !FD->isThisDeclarationADefinition() - }; - ExternObjInfoProto.push_back(Temp); - } - } - } - -private: - /*@DEVI-the structure that holds the values is global since we need it to survive through all the TUs.*/ - - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/*@DEVI-ASTContext doesn not have all the comments in a source file. i dunno why.*/ -class MCLangX23 : public MatchFinder::MatchCallback -{ -public: - MCLangX23 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mclangx23") != nullptr) - { - ASTContext *const ASTC = MR.Context; - - const SourceManager &SM = ASTC->getSourceManager(); - - RawCommentList RCL = ASTC->Comments; - - ArrayRef RawCommentArrRef = RCL.getComments(); - - std::string RawText; - - size_t matchLoc; - - unsigned currentLoc = 1U; - - unsigned MatchCounter = 0U; - - for (auto &iter : RawCommentArrRef) - { - RawText = iter->getRawText(SM); - - SourceLocation RCSL = iter->getLocStart(); - CheckSLValidity(RCSL); - RCSL = Devi::SourceLocationHasMacro(RCSL, Rewrite, "start"); - - while (true) - { - matchLoc = RawText.find("/*", currentLoc); - - if (matchLoc != std::string::npos) - { - currentLoc = matchLoc + 1U; - - MatchCounter++; - } - else - { - break; - } - } - - currentLoc = 1U; - - if (!once) - { - if (MatchCounter >= 1U) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, RCSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, RCSL)) - { - std::cout << "2.3:" << "character sequence \"/*\" used inside the comment:"; - std::cout << RCSL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, RCSL, "2.3", "character sequence \"/*\" used inside the comment : "); - JSONDocOUT.JSONAddElement(MR.Context, RCSL, "2.3", "character sequence \"/*\" used inside the comment : "); - } - } - } - } - - MatchCounter = 0U; - } - - once = true; - - } - } - -private: - bool once = false; - Rewriter &Rewrite [[maybe_unused]]; -}; -/**********************************************************************************************************************/ -/*@DEVI-changes done to the pointee through unaryOperators ++ and -- will not be tagged by this class. -see implementation notes for the explanation.*/ -class MCFunction167 : public MatchFinder::MatchCallback -{ -public: - MCFunction167 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcfunction167") != nullptr) - { - const ParmVarDecl* PVD = MR.Nodes.getNodeAs("mcfunction167"); - - SourceLocation SL = PVD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - QualType QT = PVD->getOriginalType(); - - ASTContext *const ASTC [[maybe_unused]] = MR.Context; - - if (!QT.isConstQualified()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "16.7:" << "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "16.7", "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const : "); - JSONDocOUT.JSONAddElement(MR.Context, SL, "16.7", "pointerType ParmVarDecl is not used to change the contents of the object it points to but is not declared as const : "); - } - } - } - } - } - } - -private: - Rewriter &Rewrite [[maybe_unused]]; -}; -/**********************************************************************************************************************/ -/*@DEVI-the match is quite simplistic. we could match for chartypes appearing as the LHS and then check the type of -the RHS expr but that leaves pointers changing the value.*/ -class MCTypes612 : public MatchFinder::MatchCallback -{ -public: - MCTypes612 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mc612exp") != nullptr) - { - bool RHSIsCharLit = false; - bool RHSIsIntLit = false; - - const Expr* LHS = MR.Nodes.getNodeAs("mc612exp"); - - if (MR.Nodes.getNodeAs("mc612charlit") != nullptr) - { - RHSIsCharLit = true; - } - - if (MR.Nodes.getNodeAs("mc612intlit") != nullptr) - { - RHSIsIntLit = true; - } - - SourceLocation SL = LHS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - QualType QT = LHS->getType(); - const clang::Type* TP = QT.getTypePtr(); - - ASTContext *const ASTC = MR.Context; - - const clang::Type* CanonTP = ASTC->getCanonicalType(TP); - - /*checking whether the unqualified type is simple char*/ - if (CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_S)) - { - if (RHSIsIntLit) - { - std::cout << "6.1:" << "Simple char type should only hold character values:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.1", "Simple char type should only hold character values:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.1", "Simple char type should only hold character values:"); - } - } - - if (CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UChar) || CanonTP->isSpecificBuiltinType(BuiltinType::Kind::SChar)) - { - if (RHSIsCharLit) - { - std::cout << "6.2:" << "Signed or unsigned char type should only hold numeric values:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "6.2", "Signed or unsigned char type should only hold numeric values:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "6.2", "Signed or unsigned char type should only hold numeric values:"); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCF143 : public MatchFinder::MatchCallback -{ -public: - MCCF143 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccf143nullstmt") != nullptr) - { - const NullStmt* NS = MR.Nodes.getNodeAs("mccf143nullstmt"); - - SourceLocation SL = NS->getSemiLoc(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - ASTContext *const ASTC = MR.Context; - - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - const SourceManager &SM = FSL.getManager(); - - StringRef FileNameString = SM.getFilename(SL); - - NullStmtInfo Temp = {FSL.getSpellingColumnNumber(), FSL.getSpellingLineNumber(), FileNameString, SM.isInMainFile(SL), SM.isInSystemHeader(SL)}; - - NullStmtProto.push_back(Temp); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr1212 : public MatchFinder::MatchCallback -{ -public: - MCExpr1212 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr1212") != nullptr) - { - const RecordDecl* RD = MR.Nodes.getNodeAs("mcexpr1212"); - - SourceLocation SL = RD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - std::cout << "12.12:" << "Possible violation of 12.12-access to the underlying bit representation of a floating type:"; - std::cout << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.12", "Possible violation of 12.12-access to the underlying bit representation of a floating type:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.12", "Possible violation of 12.12-access to the underlying bit representation of a floating type:"); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCExpr1211 : public MatchFinder::MatchCallback -{ -public: - MCExpr1211 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcexpr1211") != nullptr) - { - const Expr* EXP = MR.Nodes.getNodeAs("mcexpr1211"); - - SourceLocation SL = EXP->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - SourceLocation SLE = EXP->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - - std::string targetExpr = Rewrite.getRewrittenText(SR); - - ASTContext *const ASTC = MR.Context; - - QualType QT = EXP->getType(); - - const clang::Type* TP = QT.getTypePtr(); - - const clang::Type* CanonTP = ASTC->getCanonicalType(TP); - - bool TypeIsUSignedInt = CanonTP->isSpecificBuiltinType(BuiltinType::Kind::ULong) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UInt) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UShort) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UChar) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::Char_U) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::ULongLong) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::UInt128) || \ - CanonTP->isSpecificBuiltinType(BuiltinType::Kind::WChar_U); - -#if 0 - bool TypeIsUSignedInt = false; - if (CanonTP) { - auto placeholderType = CanonTP->getAsPlaceholderType(); - if (placeholderType) { - TypeIsUSignedInt = placeholderType->isUnsignedInteger(); - } - } -#endif - - if (TypeIsUSignedInt) - { - int64_t UnoFinal = 0; - int64_t DousFinal = 0; - bool MatchedUno = false; - bool MatchedDous = false; - - /*@DEVI-compilers that actually treat post and pre inc or dec need more. this doesnt support that.*/ - if (MR.Nodes.getNodeAs("mcexpr1211uno") != nullptr) - { - MatchedUno = true; - - const UnaryOperator* UO = MR.Nodes.getNodeAs("mcexpr1211uno"); - - clang::UnaryOperator::Opcode UnoOpKind = UO->getOpcode(); - - const Expr* UnoSubEXP = UO->getSubExpr(); - - llvm::APSInt UnoResult; - - UnoFinal = UnoResult.getExtValue(); - - if (UnoSubEXP->EvaluateAsInt(UnoResult, *ASTC)) - { - if (UnoOpKind == UO_PostInc || UnoOpKind == UO_PreInc) - { - UnoFinal++; - } - else if (UnoOpKind == UO_PostDec || UnoOpKind == UO_PreDec) - { - UnoFinal--; - } - else - { - /*intentionally left blank. we cant get anything else. were only matching for these two unaryoperators.*/ - } - } - } - - if (MR.Nodes.getNodeAs("mcexpr1211dous") != nullptr) - { - MatchedDous = true; - - const BinaryOperator* BO = MR.Nodes.getNodeAs("mcexpr1211dous"); - - clang::BinaryOperator::Opcode DousOpKind = BO->getOpcode(); - - const Expr* DousLHS = BO->getLHS(); - const Expr* DousRHS = BO->getRHS(); - - llvm::APSInt DousLHSAPS; - llvm::APSInt DousRHSAPS; - - if (DousLHS->EvaluateAsInt(DousLHSAPS, *ASTC) && DousRHS->EvaluateAsInt(DousRHSAPS, *ASTC)) - { - int64_t DousLHSInt64 = DousLHSAPS.getExtValue(); - int64_t DousRHSInt64 = DousRHSAPS.getExtValue(); - - switch (DousOpKind) - { - case BO_Add: - DousFinal = DousRHSInt64 + DousLHSInt64; - break; - case BO_Sub: - DousFinal = DousRHSInt64 - DousLHSInt64; - break; - case BO_Div: - DousFinal = DousRHSInt64 / DousLHSInt64; - break; - case BO_Mul: - DousFinal = DousRHSInt64 * DousLHSInt64; - break; - default: - /*cant really happen, were not matching anything else.*/ - break; - } - } - } - - llvm::APSInt OverflowCondidate; - - EXP->EvaluateAsInt(OverflowCondidate, *ASTC); - - int64_t IntExprValue = OverflowCondidate.getExtValue(); - - if ((MatchedDous && (DousFinal != IntExprValue)) || (MatchedUno && (UnoFinal != IntExprValue))) - { - std::cout << "12.11" << ":" << "Constant Unsinged Expr evaluation resuslts in an overflow:" << SL.printToString(*MR.SourceManager) << ":" << IntExprValue << " " << DousFinal << " " << ":" << targetExpr << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "12.11", "Constant Unsinged Expr evaluation resuslts in an overflow:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "12.11", "Constant Unsinged Expr evaluation resuslts in an overflow:"); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCATC105 : public MatchFinder::MatchCallback -{ -public: - MCATC105 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mcatc105lhs") != nullptr) - { - bool ShouldBeTagged = false; - SourceLocation SL; - const Expr* IgnoreImplicitEXP; - ast_type_traits::DynTypedNode DynOpNode; - - if (MR.Nodes.getNodeAs("mcatc105") != nullptr) - { - const BinaryOperator* BO = MR.Nodes.getNodeAs("mcatc105"); - DynOpNode = ast_type_traits::DynTypedNode::create(*BO); - - SL = BO->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - if (MR.Nodes.getNodeAs("mcatc105uno") != nullptr) - { - const UnaryOperator* UO = MR.Nodes.getNodeAs("mcatc105uno"); - DynOpNode = ast_type_traits::DynTypedNode::create(*UO); - - SL = UO->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - } - - const Expr* EXP = MR.Nodes.getNodeAs("mcatc105lhs"); - IgnoreImplicitEXP = EXP->IgnoreImpCasts(); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - ASTContext *const ASTC = MR.Context; - - const TargetInfo &TI = ASTC->getTargetInfo(); - - unsigned int ShortSize = TI.getShortWidth(); - - QualType QT = IgnoreImplicitEXP->getType(); - const clang::Type* TP = QT.getTypePtr(); - - const clang::Type* CanonTP = ASTC->getCanonicalType(TP); - - if (CanonTP->isUnsignedIntegerType() || CanonTP->isSignedIntegerType() || CanonTP->isAnyCharacterType()) - { - - /*@DEVI-assumptions:nothing has more than one parent in C.*/ - if (ShortSize == ASTC->getTypeSize(QT) || 8U == ASTC->getTypeSize(QT)) - { - /*@DEVI-assumes there is only one parent for every node which is true only for C, not Cpp*/ - ASTContext::DynTypedNodeList NodeList = ASTC->getParents(DynOpNode); - ast_type_traits::DynTypedNode ParentNode; - if (!NodeList.empty()) ParentNode = NodeList[0U]; - else return void(); - - ASTContext::DynTypedNodeList AncestorNodeList = ASTC->getParents(ParentNode); - - ast_type_traits::DynTypedNode AncestorNode; - if (!AncestorNodeList.empty()) AncestorNode = AncestorNodeList[0U]; - else return void(); - - ast_type_traits::ASTNodeKind ParentNodeKind = ParentNode.getNodeKind(); - ast_type_traits::ASTNodeKind AncestorNodeKind = AncestorNode.getNodeKind(); - - std::string ParentStringKind = ParentNodeKind.asStringRef().str(); - std::string AncestorStringKind = AncestorNodeKind.asStringRef().str(); - - if (ParentStringKind == "CStyleCastExpr") - { - const CStyleCastExpr* CSCE = ParentNode.get(); - - if (CSCE->getType() != QT) - { - ShouldBeTagged = true; - } - } - else if (ParentStringKind == "ParenExpr" && AncestorStringKind == "CStyleCastExpr") - { - const CStyleCastExpr* CSCE = AncestorNode.get(); - - if (CSCE->getType() != QT) - { - ShouldBeTagged = true; - } - } - else - { - ShouldBeTagged = true; - } - - if (ShouldBeTagged) - { - std::cout << "10.5" << ":" << "Result of operands << or ~ must be explicitly cast to the type of the expression:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "10.5", "Result of operands << or ~ must be explicitly cast to the type of the expression:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "10.5", "Result of operands << or ~ must be explicitly cast to the type of the expression:"); - - if (mutagen) - { - ME.ExtractAncestry(ast_type_traits::DynTypedNode::create(*EXP), *MR.Context); - } - } - } - } - -#if 0 - const BuiltinType* BT = CanonTP->getAsPlaceholderType(); - const LangOptions &LO = ASTC->getLangOpts(); - std::string something = TypeName::getFullyQualifiedName(QT, *ASTC, true); - StringRef BTName = BT->getName(PrintingPolicy(LO)); -#endif - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCCSE135 : public MatchFinder::MatchCallback -{ -public: - MCCSE135 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mccse135") != nullptr) - { - const ForStmt* FS = MR.Nodes.getNodeAs("mccse135"); - - SourceLocation SL = FS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - ASTContext *const ASTC = MR.Context; - - const Expr* FSCond = FS->getCond(); - const Expr* FSInc = FS->getInc(); - const Stmt* FSInit = FS->getInit(); - - bool CondPresent = (FSCond != nullptr); - bool DIncPresent = (FSInc != nullptr); - bool InitPresent = (FSInit != nullptr); - - /*@DEVI-for the third one we are not checking to see whether the loop counter has been previously initialized.*/ - if (!((CondPresent && DIncPresent && InitPresent) || (!CondPresent && !DIncPresent && !InitPresent) || (CondPresent && DIncPresent && !InitPresent))) - { - std::cout << "13.5" << ":" << "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The three expressions of a ForStmt shall either all exist or not exist at all or only the initialization can be missing:"); - } - - if (FSInc != nullptr) - { - if (!FSInc->HasSideEffects(*ASTC, true)) - { - std::cout << "13.5" << ":" << "The increment expression in the ForStmt has no side-effects:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The increment expression in the ForStmt has no side-effects:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The increment expression in the ForStmt has no side-effects:"); - } - } - - if (FSCond != nullptr) - { - if (FSCond->HasSideEffects(*ASTC, true)) - { - std::cout << "13.5" << ":" << "The condition expression in the ForStmt has side-effect:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The condition expression in the ForStmt has side-effect:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The condition expression in the ForStmt has side-effect:"); - } - - if (!FSCond->isKnownToHaveBooleanValue()) - { - std::cout << "13.5" << ":" << "The expression in the ForStmt condition does not return a boolean:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "13.5", "The expression in the ForStmt condition does not return a boolean:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "13.5", "The expression in the ForStmt condition does not return a boolean:"); - } - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCConst71 : public MatchFinder::MatchCallback -{ -public: - MCConst71 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - std::string TagCandidateString; - SourceLocation SL; - - if (MR.Nodes.getNodeAs("mcconst71int") != nullptr) - { - const IntegerLiteral* IL = MR.Nodes.getNodeAs("mcconst71int"); - - SourceRange SR; - SL = IL->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SR.setBegin(SL); - SourceLocation SLE = IL->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); - SR.setEnd(SLE); - - TagCandidateString = Rewrite.getRewrittenText(SR); - } - - if (MR.Nodes.getNodeAs("mcconst71string") != nullptr) - { - const clang::StringLiteral* StringLit = MR.Nodes.getNodeAs("mcconst71string"); - - SL = StringLit->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "strat"); - - TagCandidateString = StringLit->getString().str(); - } - - if (MR.Nodes.getNodeAs("mcconst71char") != nullptr) - { - const CharacterLiteral* CL = MR.Nodes.getNodeAs("mcconst71char"); - - SL = CL->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - SourceRange SR; - SourceLocation SLE = CL->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "start"); - SR.setBegin(SL); - SR.setEnd(SLE); - - TagCandidateString = Rewrite.getRewrittenText(SR); - } - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::regex octalconstant("\\\\[0-7]+"); - std::regex octalconstantint("^0[0-9]+$"); - std::regex hexescapesequence("\\\\x[0-9a-fA-F]+"); - std::regex otherescapesequence("\\\\[^0-9abfnrtvx'\"\\?]"); - - std::smatch result; - -#if 0 - std::cout << "diagnostic2:" << TagCandidateString << ":" << SL.printToString(*MR.SourceManager) << ":" << std::regex_search(TagCandidateString, result, octalconstant) << "\n"; -#endif - - if (std::regex_search(TagCandidateString, result, octalconstant) || std::regex_search(TagCandidateString, result, octalconstantint)) - { - std::cout << "7.1" << ":" << "Octal escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "7.1", "Octal escape sequence used:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "7.1", "Octal escape sequence used:"); - } - - if (std::regex_search(TagCandidateString, result, hexescapesequence)) - { - std::cout << "4.1" << ":" << "Hexadecimal escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "4.1", "Hexadecimal escape sequence used:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "4.1", "Hexadecimal escape sequence used:"); - } - - if (std::regex_search(TagCandidateString, result, otherescapesequence)) - { - std::cout << "4.1" << ":" << "Non-standard escape sequence used:" << SL.printToString(*MR.SourceManager) << ":" << TagCandidateString << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "4.1", "Non-standard escape sequence used:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "4.1", "Non-standard escape sequence used:"); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MCIdent5x : public MatchFinder::MatchCallback -{ -public: - MCIdent5x (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("ident5typedef") != nullptr) - { - const TypedefDecl* BN = MR.Nodes.getNodeAs("ident5typedef"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name = II->getName().str(); - - SourceManager *const SM = MR.SourceManager; - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::TypedefDecl, \ - false, Devi::FunctionDeclKind::NoValue, Devi::Scope::TU, "", true, false - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5record") != nullptr) - { - const RecordDecl* BN = MR.Nodes.getNodeAs("ident5record"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::RecordDecl, \ - BN->getTypeForDecl()->isIncompleteType(), Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5field") != nullptr) - { - const FieldDecl* BN = MR.Nodes.getNodeAs("ident5field"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::FieldDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false - }; - - IdentInfoProto.push_back(Temp); - } - - /*@DEVI-dunno how it will handle incomplete records passed as parmvars.*/ - if (MR.Nodes.getNodeAs("ident5parmvar") != nullptr) - { - const ParmVarDecl* BN = MR.Nodes.getNodeAs("ident5parmvar"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::ParmVarDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, BN->isStaticLocal() - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5func") != nullptr) - { - const FunctionDecl* BN = MR.Nodes.getNodeAs("ident5func"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - Devi::FunctionDeclKind tempfkind; - - if (BN->isThisDeclarationADefinition()) - { - tempfkind = Devi::FunctionDeclKind::Definition; - } - else - { - tempfkind = Devi::FunctionDeclKind::Declaration; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::FunctionDecl, \ - false, tempfkind, Devi::Scope::TU, "", true, false - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5var") != nullptr) - { - const VarDecl* BN = MR.Nodes.getNodeAs("ident5var"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::VarDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, BN->isStaticLocal() - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5enum") != nullptr) - { - const EnumDecl* BN = MR.Nodes.getNodeAs("ident5enum"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::EnumDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5label") != nullptr) - { - const LabelDecl* BN = MR.Nodes.getNodeAs("ident5label"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::LabelDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false - }; - - IdentInfoProto.push_back(Temp); - } - - if (MR.Nodes.getNodeAs("ident5enumconst") != nullptr) - { - const EnumConstantDecl* BN = MR.Nodes.getNodeAs("ident5enumconst"); - - SourceLocation SL = BN->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const IdentifierInfo* II = BN->getIdentifier(); - - std::string Name; - - if (II != nullptr) - { - Name = II->getName().str(); - } - - SourceManager *const SM = MR.SourceManager; - - std::string FunctionName; - - if (MR.Nodes.getNodeAs("id5funcscope") != nullptr) - { - const FunctionDecl* FD = MR.Nodes.getNodeAs("id5funcscope"); - - FunctionName = FD->getNameAsString(); - } - - Devi::Scope tempscope = Devi::Scope::TU; - - if (FunctionName != "") - { - tempscope = Devi::Scope::Block; - } - - IdentInfo Temp = {SM->getSpellingLineNumber(SL), SM->getSpellingColumnNumber(SL), \ - SM->getFilename(SL).str(), Name, SL.printToString(*SM), Devi::NodeKind::EnumConstDecl, \ - false, Devi::FunctionDeclKind::NoValue, tempscope, FunctionName, true, false - }; - - IdentInfoProto.push_back(Temp); - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/** - * @brief Tags all array declarations and uses of arrays through indexes. - */ -class SFCPPARR01 : public MatchFinder::MatchCallback -{ - public: - SFCPPARR01 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - /** - * @brief The virtual method that runs the tagging. - * - * @param MR MatchFinder::MatchResulet - */ - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("sfcpparrdecl") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("sfcpparrdecl"); - - SourceLocation SL = VD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "SaferCPP01" << ":" << "Native CPP array declared:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array declared:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP array declared:"); - } - - if (MR.Nodes.getNodeAs("sfcpparrcastexpr") != nullptr) - { - const CastExpr* CS = MR.Nodes.getNodeAs("sfcpparrcastexpr"); - - SourceLocation SL = CS->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "SaferCPP01" << ":" << "Native CPP array used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array used"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP arry=ay used"); - } - - if (MR.Nodes.getNodeAs("sfcpparrfield") != nullptr) - { - const FieldDecl* FD = MR.Nodes.getNodeAs("sfcpparrfield"); - - SourceLocation SL = FD->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "SaferCPP01" << ":" << "Native CPP array field used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native CPP array field used"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native CPP arryay field used"); - } - } - - private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/** - * @brief The matcher run by SFCPPARR02. This ones does all the real tagging. - */ -class SFCPPARR02SUB : public MatchFinder::MatchCallback -{ - public: - SFCPPARR02SUB (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("sfcpp02sub") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpp02sub"); - - SourceManager *const SM = MR.SourceManager; - - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - //SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SL = SM->getSpellingLoc(SL); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - const NamedDecl* ND = DRE->getFoundDecl(); - - SourceLocation OriginSL = ND->getLocStart(); - CheckSLValidity(OriginSL); - //OriginSL = Devi::SourceLocationHasMacro(OriginSL, Rewrite, "start"); - OriginSL = SM->getSpellingLoc(OriginSL); - - StringRef OriginFileName [[maybe_unused]] = SM->getFilename(OriginSL); - -#if 0 - std::cout << "GarbageOut" << ":" << "Origin:" << DRE->getFoundDecl()->getName().str() << "\n"; - std::cout << "GarbageOut" << ":" << "Origin:" << ExtOriginFileName.str() << ":" << "Proto:" << OriginFileName.str() << "\n"; - std::cout << "GarbageOut" << ":" << "Origin:" << ExtOriginSL.printToString(*SM) << ":" << "Proto:" << OriginSL.printToString(*SM) << "\n"; -#endif - - if (OriginSL == ExtOriginSL && OriginFileName == ExtOriginFileName) - { - std::cout << "SaferCPP01" << ":" << "Native Array used - pointer points to an array:" << SL.printToString(*MR.SourceManager) << ":" << DRE->getFoundDecl()->getName().str() << "\n"; - } - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP01", "Native Array used - pointer points to an array:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP01", "Native Array used - pointer points to an array:"); - } - } - - void setOriginSourceLocation(SourceLocation inSL) - { - ExtOriginSL = inSL; - } - - void setOriginFileName(StringRef inStrRef) - { - ExtOriginFileName = inStrRef; - } - - private: - Rewriter &Rewrite [[maybe_unused]]; - SourceLocation ExtOriginSL; - StringRef ExtOriginFileName; -}; -/**********************************************************************************************************************/ -/** - * @brief MatchCallback for safercpp matching of pointers pointing to arrays. - */ -class SFCPPARR02 : public MatchFinder::MatchCallback -{ - public: - SFCPPARR02 (Rewriter &Rewrite) : Rewrite(Rewrite), SubHandler(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("sfcpparrdeep") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpparrdeep"); - - ASTContext *const ASTC = MR.Context; - - SourceManager *const SM = MR.SourceManager; - - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - SL = SM->getSpellingLoc(SL); - - const NamedDecl* ND = DRE->getFoundDecl(); - - StringRef NDName = ND->getName(); - - SubHandler.setOriginSourceLocation(SM->getSpellingLoc(ND->getLocStart())); - SubHandler.setOriginFileName(SM->getFilename(SM->getSpellingLoc(ND->getLocStart()))); - - Matcher.addMatcher(declRefExpr(to(varDecl(hasName(NDName.str())))).bind("sfcpp02sub"), &SubHandler); - - Matcher.matchAST(*ASTC); - -#if 0 - std::cout << "GarbageOutOrigin" << ":" << "GarbageOutOrigin:" << SL.printToString(*MR.SourceManager) << ":" << NDName.str() << "\n"; -#endif - } - } - - private: - Rewriter &Rewrite [[maybe_unused]]; - MatchFinder Matcher; - SFCPPARR02SUB SubHandler; -}; -/**********************************************************************************************************************/ -/** - * @brief The callback for the Safercpp pointer matchers. Matches the dedlarations. - */ -class SFCPPPNTR01 : public MatchFinder::MatchCallback -{ - public: - SFCPPPNTR01 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("sfcpppntr01") != nullptr) - { - const VarDecl* VD = MR.Nodes.getNodeAs("sfcpppntr01"); - - SourceLocation SL = VD->clang::Decl::getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "SaferCPP02" << ":" << "Native pointer declared:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP02", "Native pointer declared:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP02", "Native pointer declared:"); - } - } - - private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/** - * @brief The callback for the Safercpp pointer matchers. Matches the DeclRefExprs. - */ -class SFCPPPNTR02 : public MatchFinder::MatchCallback -{ - public: - SFCPPPNTR02 (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("sfcpppntr02") != nullptr) - { - const DeclRefExpr* DRE = MR.Nodes.getNodeAs("sfcpppntr02"); - - SourceLocation SL = DRE->getLocStart(); - CheckSLValidity(SL); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL)) - { - return void(); - } - - std::cout << "SaferCPP02" << ":" << "Native pointer used:" << SL.printToString(*MR.SourceManager) << ":" << "\n"; - - XMLDocOut.XMLAddNode(MR.Context, SL, "SaferCPP02", "Native pointer used:"); - JSONDocOUT.JSONAddElement(MR.Context, SL, "SaferCPP02", "Native pointer used:"); - } - } - - private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/**********************************************************************************************************************/ -/*the sourcelocation used in the overload of XMLAddNode that takes sourcemanager as input parameter uses -the spelling location so the client does not need to check the sourcelocation for macros expansions.*/ -class PPInclusion : public PPCallbacks -{ -public: - explicit PPInclusion (SourceManager *SM) : SM(*SM) {} - - /*@DEVI-if we dont throw an exception for a bad header inclusion, we wil crash later on since we have InclusionDirective PPCallback.*/ - virtual bool FileNotFound(StringRef FileName, SmallVectorImpl &RecoveryPath) - { - std::cerr << "\033[1;31mHeader Not Found: " << FileName.str() << "\033[0m" << "\n"; -#if 0 - std::abort(); -#endif - throw MutExHeaderNotFound(FileName.str()); - } - - virtual void InclusionDirective (SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, \ - bool IsAngled, CharSourceRange FileNameRange, const FileEntry* File, \ - StringRef SearchPath, StringRef RelativePath, const clang::Module* Imported) - { - - CheckSLValidity(HashLoc); - -#if defined(__linux__) - std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); - std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); -#elif defined(__MACH__) && defined(__APPLE__) - std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); - std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); -#elif defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) - std::ifstream HeaderABS(SearchPath.str() + "\\" + FileName.str()); - std::ifstream HeaderRel(RelativePath.str() + "\\" + FileName.str()); -#else - std::ifstream HeaderABS(SearchPath.str() + "/" + FileName.str()); - std::ifstream HeaderRel(RelativePath.str() + "/" + FileName.str()); -#endif - - if (File->isValid() && (HeaderABS.good() || HeaderRel.good())) - { -#if 0 - assert(HashLoc.isValid() && "The SourceLocation for InclusionDirective is invalid."); -#endif - -#if 1 - if (IsAngled) - { - size_t singleQPos = FileName.find("\'", 0); - size_t doubleQPos = FileName.find("\"", 0); - size_t whateverSlashPos = FileName.find("\\", 0); - size_t commentPos = FileName.find("\\*", 0); - - if (singleQPos != std::string::npos || doubleQPos != std::string::npos || whateverSlashPos != std::string::npos || commentPos != std::string::npos) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "19.2:" << "illegal characters in inclusion directive:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); - } - } - } - - if (FileName == "errno.h") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "20.5:" << "errno shall not be used:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "20.5", "errno shall not be used : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "20.5", "errno shall not be used : "); - } - } - } - - if (FileName == "time.h") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "20.12:" << "stdlib time.h is included in the project. use is forbidden:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "20.12", "stdlib time.h is included in the project. use is forbidden : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "20.12", "stdlib time.h is included in the project. use is forbidden : "); - } - } - } - - if (FileName == "stdio.h") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "20.9:" << "stdlib stdio.h is included in the project. use is forbidden:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "20.9", "stdlib stdio.h is included in the project. use is forbidden : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "20.9", "stdlib stdio.h is included in the project. use is forbidden : "); - } - } - } - - if (FileName == "signal.h") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "20.8:" << "stdlib signal.h is included in the project. use is forbidden:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "20.8", "stdlib signal.h is included in the project. use is forbidden : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "20.8", "stdlib signal.h is included in the project. use is forbidden : "); - } - } - } - } - else - { - size_t singleQPos = FileName.find("\'", 0); - size_t whateverSlashPos = FileName.find("\\", 0); - size_t commentPos = FileName.find("\\*", 0); - - if (singleQPos != std::string::npos || whateverSlashPos != std::string::npos || commentPos != std::string::npos) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "19.2:" << "illegal characters in inclusion directive:"; - std::cout << HashLoc.printToString(SM) << "\n" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "19.2", "illegal characters in inclusion directive : "); - } - } - } - - bool IsNewIncludeFile = true; - - for (unsigned x = 0; x < IncludeFileArr.size(); ++x) - { - if (SearchPath.str() + "/" + FileName.str() == IncludeFileArr[x]) - { - IsNewIncludeFile = false; - break; - } - } - - /*its supposed to supprt linux and cygwin,mingw and mac builds.*/ - if (IsNewIncludeFile) - { -#if defined(__linux__) - IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); -#elif defined(__MACH__) && defined(__APPLE__) - IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); -#elif defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) - IncludeFileArr.push_back(SearchPath.str() + "\\" + FileName.str()); -#else - IncludeFileArr.push_back(SearchPath.str() + "/" + FileName.str()); -#endif - } - } - - size_t whateverSlashPos = FileName.find("\\", 0); - size_t theotherSlashPos = FileName.find(" / ", 0); - - if (whateverSlashPos != std::string::npos || theotherSlashPos != std::string::npos) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, HashLoc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, HashLoc)) - { - std::cout << "19.3:" << "Include directive contains file address, not just name:"; - std::cout << HashLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, HashLoc, "19.3", "Include directive contains file address, not just name : "); - JSONDocOUT.JSONAddElement(SM, HashLoc, "19.3", "Include directive contains file address, not just name : "); - } - } - } -#endif - } - } - - /*@DEVI-if the macro is not checked for being defined before almost any kind of use, the code will break in seemingly random ways.*/ - /*@DEVI-FIXME-the macro definition is the definition of the macro passed to defined. not sure what happens if there are more than two. - basically i dont know how to just get the tokens after defined.*/ - virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) - { -#if 1 - SourceLocation SL [[maybe_unused]] = Range.getBegin(); - CheckSLValidity(SL); - -#if 0 - assert(SL.isValid(), "the SourceLocation for macro Defined is not valid."); -#endif - - const MacroInfo* MI = MD.getMacroInfo(); - - DefMacroDirective* DMD = MD.getLocalDirective(); - - bool ShouldBeTagged194 = false; - -#if 1 - if (DMD) - { - if (DMD->isDefined()) - { - if (!MI->tokens_empty()) - { - ArrayRef TokenArrayRef = MI->tokens(); - - unsigned NumOfTokens = MI->getNumTokens(); - - if (NumOfTokens == 1U) - { - if (!(TokenArrayRef[0].getKind() == tok::identifier)) - { - ShouldBeTagged194 = true; - } - } - else if (NumOfTokens == 3U) - { - if (!(TokenArrayRef[0].getKind() == tok::l_paren && TokenArrayRef[1].getKind() == tok::identifier && TokenArrayRef[2].getKind() == tok::r_paren)) - { - ShouldBeTagged194 = true; - } - } - else - { - ShouldBeTagged194 = true; - } - } - else - { - ShouldBeTagged194 = true; - } - - if (ShouldBeTagged194) - { -#if 0 - std::cout << "19.14 : " << "Illegal \"defined\" form : " << "\n"; - std::cout << SL.printToString(SM) << "\n" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.14", "Illegal \"defined\" form : "); -#endif - } - } - } -#endif -#endif - } - - virtual void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef) - { -#if 1 - const MacroInfo* MI = MD.getMacroInfo(); - - DefMacroDirective* DMD = MD.getLocalDirective(); - - if (MI != nullptr && DMD != nullptr) - { - SourceLocation SL = MacroNameTok.getLocation(); - CheckSLValidity(SL); - -#if 0 - assert(SL.isValid(), "the SourceLocation for MacroUndefined is not valid."); -#endif - - /*start of 20.1*/ - /*inline and restrict are C99*/ - if (MacroNameTok.isOneOf(tok::kw_auto, tok::kw_break, tok::kw_case, tok::kw_char, tok::kw_const, tok::kw_continue, \ - tok::kw_default, tok::kw_do, tok::kw_double, tok::kw_else, tok::kw_enum, tok::kw_extern, \ - tok::kw_float, tok::kw_for, tok::kw_goto, tok::kw_if, tok::kw_inline, tok::kw_int, tok::kw_long, \ - tok::kw_register, tok::kw_restrict, tok::kw_return, tok::kw_short, tok::kw_signed, tok::kw_sizeof, \ - tok::kw_static, tok::kw_struct, tok::kw_switch, \ - tok::kw_typedef, tok::kw_union, tok::kw_unsigned, tok::kw_void, tok::kw_volatile, tok::kw_while)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "20.1:" << "C keyword undefined:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.1", "C keyword undefined : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C keyword undefined : "); - } - } - } - - if (DMD->getPrevious() != nullptr) - { - const MacroDirective* PMD = DMD->getPrevious(); - - if (PMD != nullptr) - { - SourceLocation PSL = PMD->getLocation(); - CheckSLValidity(PSL); - - if (SM.isInSystemHeader(PSL) || MI->isBuiltinMacro()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "20.1:" << "C standard library macro undefined:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.1", "C standard library macro undefined : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C standard library macro undefined : "); - } - } - } - } - } - /*end of 20.1*/ - - /*start of 19.5*/ - if (!MI->isBuiltinMacro() && SM.isInMainFile(SL) && !SM.isInSystemHeader(SL)) - { - MacroUndefSourceLocation.push_back(SL); - } - /*end of 19.5*/ - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.6:" << "Use of #undef is illegal:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.6", "Use of #undef is illegal : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.6", "Use of #undef is illegal : "); - } - } - } -#endif - } - - virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) - { -#if 1 - const MacroInfo* MI = MD->getMacroInfo(); - - SourceLocation SL = MacroNameTok.getLocation(); - CheckSLValidity(SL); - -#if 0 - assert(SL->isValid(), "the SourceLocation for MacroDefined is not valid."); -#endif - -#if __clang_major__ < 5 - unsigned MacroNumArgs = MI->getNumArgs(); -#elif __clang_major__ >= 5 - unsigned MacroNumArgs = MI->getNumParams(); -#endif - - /*start of 19.5*/ - if (!MI->isBuiltinMacro() && SM.isInMainFile(SL) && !SM.isInSystemHeader(SL)) - { - MacroDefSourceLocation.push_back(SM.getExpansionLoc(SL)); - MacroNameString.push_back(MacroNameTok.getIdentifierInfo()->getName().str()); - } - /*end of 19.5*/ - - /*start of 20.1*/ - /*inline and restrict are C99*/ - if (MacroNameTok.isOneOf(tok::kw_auto, tok::kw_break, tok::kw_case, tok::kw_char, tok::kw_const, tok::kw_continue, \ - tok::kw_default, tok::kw_do, tok::kw_double, tok::kw_else, tok::kw_enum, tok::kw_extern, \ - tok::kw_float, tok::kw_for, tok::kw_goto, tok::kw_if, tok::kw_inline, tok::kw_int, tok::kw_long, \ - tok::kw_register, tok::kw_restrict, tok::kw_return, tok::kw_short, tok::kw_signed, tok::kw_sizeof, \ - tok::kw_static, tok::kw_struct, tok::kw_switch, \ - tok::kw_typedef, tok::kw_union, tok::kw_unsigned, tok::kw_void, tok::kw_volatile, tok::kw_while)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "20.1:" << "C keyword defined:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.1", "C keyword defined : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C keyword defined : "); - } - } - } - - if (MD->getPrevious() != nullptr) - { - const MacroDirective* PMD = MD->getPrevious(); - SourceLocation PSL = PMD->getLocation(); - /*@DEVI-A quick fix.Fixme.*/ - CheckSLValidity(PSL); - - if (SM.isInSystemHeader(PSL) || MI->isBuiltinMacro()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "20.1:" << "C standard library macro redefined:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.1", "C standard library macro redefined : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.1", "C standard library macro redefined : "); - } - } - } - } - /*end of 20.1*/ - - ArrayRef TokenArrayRef = MI->tokens(); -#if __clang_major__ < 5 - ArrayRef MacroArgsArrRef = MI->args(); -#elif __clang_major__ >= 5 - ArrayRef MacroArgsArrRef = MI->params(); -#endif - - unsigned NumOfTokens = MI->getNumTokens(); - - bool hasSingleHash = false; - bool hasDoubleHash = false; - - for (unsigned x = 0; x < NumOfTokens; ++x) - { -#if 1 - if (TokenArrayRef[x].getKind() == tok::hash) - { - hasSingleHash = true; - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.13:" << "Macro has # token:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.13", "Macro has # token : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.13", "Macro has # token : "); - } - } - } - - if (TokenArrayRef[x].getKind() == tok::hashhash) - { - hasDoubleHash = true; - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.13:" << "Macro has ## token:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.13", "Macro has ## token : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.13", "Macro has ## token : "); - } - } - } -#endif - } - - if (hasSingleHash && hasDoubleHash) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.12:" << "Macro has # and ## tokens:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.12", "Macro has # and ## tokens : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.12", "Macro has # and ## tokens : "); - } - } - } - - if (MI->isFunctionLike()) - { - bool ShouldBeTagged = false; - bool IsIdentifierMacroArg = false; - bool HasHash = false; - - for (unsigned x = 0U; x < NumOfTokens; ++x) - { -#if 1 - /*@DEVI-for macro defs that dont have more than two token NumOfTokens will wrap around since its - unsigned if subtracted by two,hence the check. it does not hurt the logic since if there are less - than two token in a macro definition, then it cannot possibly have a hash or a double hash.*/ - if (NumOfTokens >= 2U) - { - if (TokenArrayRef[x].getKind() == tok::identifier) - { - for (unsigned xx = 0; xx < MacroNumArgs; ++xx) - { - if (TokenArrayRef[x].getIdentifierInfo()->getName().str() == MacroArgsArrRef[xx]->getName().str()) - { - IsIdentifierMacroArg = true; - } - } - - if (IsIdentifierMacroArg) - { - if (x <= NumOfTokens - 2U) - { - if (TokenArrayRef[x + 1U].getKind() == tok::hashhash) - { - HasHash = true; - } - } - - if (x >= 1U) - { - if (TokenArrayRef[x - 1U].getKind() == tok::hash || TokenArrayRef[x - 1U].getKind() == tok::hashhash) - { - HasHash = true; - } - } - - if (x <= NumOfTokens - 2U) - { - if (!(TokenArrayRef[x + 1U].getKind() == tok::r_paren) && !HasHash) - { - ShouldBeTagged = true; - } - } - - if (x >= 1U) - { - if (!(TokenArrayRef[x - 1U].getKind() == tok::l_paren) && !HasHash) - { - ShouldBeTagged = true; - } - } - } - } - - IsIdentifierMacroArg = false; - HasHash = false; - } -#endif - } - - if (ShouldBeTagged) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.10:" << "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.10", "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.10", "Funciton-like macro's parameters are not enclosed in parantheses or dont have hash : "); - } - } - } - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.7:" << "Function-like macro used:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.7", "Function-like macro used : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.7", "Function-like macro used : "); - } - } - } - - if (MacroNumArgs != 0) - { - for (unsigned x = 0; x < MacroNumArgs; ++x) - { - if (MacroArgsArrRef[0]->hasMacroDefinition()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - std::cout << "19.9:" << "Function-like macro's argument contains macros:"; - std::cout << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.9", "Function-like macro's argument contains macros : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.9", "Function-like macro's argument contains macros : "); - } - } - - break; - } - } - } - } -#endif - } - - virtual void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) - { -#if 1 - SourceLocation SL = MacroNameTok.getLocation(); - CheckSLValidity(SL); - -#if 0 - assert(SL.isValid(), "the SourceLocation for MacroExpands is not valid."); -#endif - - IdentifierInfo* II = MacroNameTok.getIdentifierInfo(); - - std::string MacroNameString = II->getName().str(); - - DefMacroDirective* DMD = MD.getLocalDirective(); - - SourceLocation MDSL = DMD->getLocation(); - - MacroInfo* MI = MD.getMacroInfo(); - - /*start of 19.4*/ - ArrayRef TokenArrayRef = MI->tokens(); - - /*@DEVI-guard against macro defs that just define the macro without a value.*/ - if (TokenArrayRef.size() != 0U) - { - bool MacroExpansionIsTypeQualifier = true; - bool MacroExpansionIsStorageSpecifier = true; - bool MacroExpansionStringLiteral = false; - bool MacroExpansionConstant = false; - bool MacroExpansionBracedInitializer = true; - bool MacroExpansionParenExpr = true; - bool MacroExpansionDoWhileZero = true; - - if (TokenArrayRef.front().getKind() == tok::l_paren && TokenArrayRef.back().getKind() == tok::r_paren) - { - /*currently we do not care what's inside the parens.*/ - } - else - { - MacroExpansionParenExpr = false; - } - - if (TokenArrayRef.front().getKind() == tok::l_brace && TokenArrayRef.back().getKind() == tok::r_brace) - { - /*currently we don't care what's inside the curly braces.*/ - } - else - { - MacroExpansionBracedInitializer = false; - } - - //std::vector TokenPattern = {tok::kw_while, tok::l_paren, tok::numeric_constant, tok::r_paren}; - std::vector TokenPattern; - TokenPattern.push_back(tok::kw_while); - TokenPattern.push_back(tok::l_paren); - TokenPattern.push_back(tok::numeric_constant); - TokenPattern.push_back(tok::r_paren); - - if (TokenArrayRef.front().getKind() == tok::kw_do) - { - unsigned marker = 0U; - - for (ArrayRef::iterator iter = TokenArrayRef.begin(), iterE = TokenArrayRef.end(); iter != iterE; ++iter) - { - if (iter->getKind() == tok::kw_while) - { - marker = 0U; - } - - if (marker == 3U && iter->getKind() == TokenPattern[3]) - { - marker = 4U; - } - else if (marker == 3U && iter->getKind() != TokenPattern[3]) - { - marker = 0U; - } - else - { - /*empty*/ - } - - if (marker == 2U && iter->getKind() == TokenPattern[2]) - { - marker = 3U; - } - else if (marker == 2U && iter->getKind() != TokenPattern[2]) - { - marker = 0U; - } - else - { - /*empty*/ - } - - if (marker == 1U && iter->getKind() == TokenPattern[1]) - { - marker = 2U; - } - else if (marker == 1U && iter->getKind() != TokenPattern[1]) - { - - } - else - { - /*empty*/ - } - - if (marker == 0U && iter->getKind() == TokenPattern[0]) - { - marker = 1U; - } - } - - if (marker != 4U) - { - MacroExpansionDoWhileZero = false; - } - } - else - { - MacroExpansionDoWhileZero = false; - } - - if (TokenArrayRef.size() == 1U) - { - if (TokenArrayRef[0].getKind() == tok::string_literal || TokenArrayRef[0].getKind() == tok::wide_string_literal \ - || TokenArrayRef[0].getKind() == tok::utf8_string_literal || TokenArrayRef[0].getKind() == tok::utf16_string_literal \ - || TokenArrayRef[0].getKind() == tok::utf32_string_literal) - { - MacroExpansionStringLiteral = true; - } - - if (TokenArrayRef[0].getKind() == tok::numeric_constant || TokenArrayRef[0].getKind() == tok::char_constant \ - || TokenArrayRef[0].getKind() == tok::wide_char_constant || TokenArrayRef[0].getKind() == tok::utf8_char_constant \ - || TokenArrayRef[0].getKind() == tok::utf16_char_constant || TokenArrayRef[0].getKind() == tok::utf32_char_constant) - { - MacroExpansionConstant = true; - } - } - - for (auto &iter : TokenArrayRef) - { - if (iter.getKind() == tok::kw_const || iter.getKind() == tok::kw_restrict || iter.getKind() == tok::kw_volatile \ - || iter.getKind() == tok::l_paren || iter.getKind() == tok::r_paren) - { - /*has no significance*/ - } - else - { - MacroExpansionIsTypeQualifier = false; - } - - if (iter.getKind() == tok::kw_auto || iter.getKind() == tok::kw_extern || iter.getKind() == tok::kw_register \ - || iter.getKind() == tok::kw_static || iter.getKind() == tok::kw_typedef \ - || iter.getKind() == tok::l_paren || iter.getKind() == tok::r_paren) - { - /*has no significance*/ - } - else - { - MacroExpansionIsStorageSpecifier = false; - } - } - - if (!MacroExpansionIsTypeQualifier && !MacroExpansionIsStorageSpecifier \ - && !MacroExpansionStringLiteral && !MacroExpansionConstant \ - && !MacroExpansionBracedInitializer && !MacroExpansionParenExpr \ - && !MacroExpansionDoWhileZero) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) - { - std::cout << "19.4:" << "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier:"; - std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.4", "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.4", "Macro does not expand to braced initializer,panthesizes expression,string literal,constant,do-while-zero,storage class specifier or type qualifier : "); - } - } - } - } - /*end of 19.4*/ - -#if 1 - if (Args != nullptr) - { - /*@DEVI-Macro args are passed twice. first they are expanded and then the whole macro, - including the args is checked again for expansion, so args are passed twice.*/ -#if __clang_major__ == 4 - if (MI->getNumArgs() != Args->getNumArguments() - MI->getNumArgs()) -#elif __clang_major__ == 5 - if (MI->getNumParams() != Args->getNumMacroArguments() - MI->getNumParams()) -#elif __clang_major__ == 6 - if (MI->getNumParams() != Args->getNumMacroArguments() - MI->getNumParams()) -#endif - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) - { - std::cout << "19.8:" << "Funciton-like macro invoked with wrong number of arguments:"; -#if __clang_major__ == 4 - std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumArguments() << " " << MI->getNumArgs() << ":" << "\n"; -#elif __clang_major__ == 5 - std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumMacroArguments() << " " << MI->getNumParams() << ":" << "\n"; -#elif __clang_major__ == 6 - std::cout << Range.getBegin().printToString(SM) << ":" << Args->getNumMacroArguments() << " " << MI->getNumParams() << ":" << "\n"; -#endif - - XMLDocOut.XMLAddNode(SM, SL, "19.8", "Funciton-like macro invoked with wrong number of arguments:"); - JSONDocOUT.JSONAddElement(SM, SL, "19.8", "Funciton-like macro invoked with wrong number of arguments:"); - } - } - } - } -#endif - - if (MacroNameString == "offsetof") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) - { - std::cout << "20.6:" << "use of offsetof is illegal:"; - std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.6", "use of offsetof is illegal : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.6", "use of offsetof is illegal : "); - } - } - } - - if (MacroNameString == "setjmp") - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) - { - std::cout << "20.7:" << "use of setjmp is illegal:"; - std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "20.7", "use of setjmp is illegal : "); - JSONDocOUT.JSONAddElement(SM, SL, "20.7", "use of setjmp is illegal : "); - } - } - } - - if (!DMD->isDefined()) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, MDSL)) - { - /*intentionally left blank*/ - } - else - { - /*@DEVI-by the time we get a callback on our callback, the macri is assigned a default vlaue even if it is undefined in the TU.*/ - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, MDSL)) - { - std::cout << "19.11:" << "Use of undefined macro:"; - std::cout << Range.getBegin().printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SL, "19.11", "Use of undefined macro : "); - JSONDocOUT.JSONAddElement(SM, SL, "19.11", "Use of undefined macro : "); - } - } - } -#endif - } - - virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc) - { -#if 1 - SourceLocation SLoc = SM.getSpellingLoc(Loc); - CheckSLValidity(SLoc); - SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); - CheckSLValidity(SIfLoc); - - if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) - { - std::cout << "19.17:" << "elif directive is not in the same file as its if directive:"; - std::cout << SLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "elif directive is not in the same file as its if directive : "); - JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "elif directive is not in the same file as its if directive : "); - } - } - } -#endif - } - - virtual void Else(SourceLocation Loc, SourceLocation IfLoc) - { -#if 1 - SourceLocation SLoc = SM.getSpellingLoc(Loc); - CheckSLValidity(SLoc); - SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); - CheckSLValidity(SIfLoc); - - if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) - { - std::cout << "19.17:" << "else directive is not in the same file as its if directive:"; - std::cout << SLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "else directive is not in the same file as its if directive : "); - JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "else directive is not in the same file as its if directive : "); - } - } - } -#endif - } - - virtual void Endif (SourceLocation Loc, SourceLocation IfLoc) - { -#if 1 - SourceLocation SLoc = SM.getSpellingLoc(Loc); - CheckSLValidity(SLoc); - SourceLocation SIfLoc = SM.getSpellingLoc(IfLoc); - CheckSLValidity(SIfLoc); - - if (SM.getFileID(SLoc) != SM.getFileID(SIfLoc)) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, Loc)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, SM, Loc)) - { - std::cout << "19.17:" << "endif directive is not in the same file as its if directive:"; - std::cout << SLoc.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SM, SLoc, "19.17", "endif directive is not in the same file as its if directive : "); - JSONDocOUT.JSONAddElement(SM, SLoc, "19.17", "endif directive is not in the same file as its if directive : "); - } - } - } -#endif - } - -private: - const SourceManager &SM; -}; -/**********************************************************************************************************************/ -class IsThereJunkPreInclusion -{ -public: - IsThereJunkPreInclusion() {} - - void Check(std::vector SourcePathList) - { - bool HaveWeMatchedInclusionDirYet = false; - bool HaveWeMatchIllegal191Yet = false; - - for (auto &iter : SourcePathList) - { - //std::cout << iter << "\n"; - std::ifstream InputFile(iter); - - HaveWeMatchIllegal191Yet = false; - HaveWeMatchedInclusionDirYet = false; - - for (std::string line; getline(InputFile, line);) - { - //std::cout << iter << ":" << line << ":" << HaveWeMatchedInclusionDirYet << " " << HaveWeMatchIllegal191Yet << "\n"; - - if (line.empty()) - { - continue; - } - - if (line.front() == '#') - { - size_t st = line.find("#include", 0U); - - if (st == 0U) - { - /*we've found a header include*/ - HaveWeMatchedInclusionDirYet = true; - - if (HaveWeMatchIllegal191Yet) - { - /*print diag out*/ - std::cout << "19.1" << ":" << "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments" << ":" << iter << "\n"; - - XMLDocOut.XMLAddNode(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); - JSONDocOUT.JSONAddElement(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); - break; - } - else - { - break; - } - } - - continue; - } - - if (line.front() == '/') - { - /*has to be a comment*/ - continue; - } - - if (line.front() == '\n' || line.front() == '\t' || line.front() == ' ' || line.front() == '\r') - { - HaveWeMatchIllegal191Yet = false; - - for (auto &iterchar : line) - { - if (iterchar == '\n' || iterchar == '\t' || iterchar == ' ' || line.front() == '\r') - { - continue; - } - - if (iterchar == '/') - { - break; - } - - if (iterchar == '#') - { - size_t st = line.find("#include", 0U); - - if (st == 0U) - { - /*we've found a header include*/ - HaveWeMatchedInclusionDirYet = true; - - if (HaveWeMatchIllegal191Yet) - { - /*print diag out*/ - std::cout << "19.1" << ":" << "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments" << ":" << iter << "\n"; - - XMLDocOut.XMLAddNode(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); - JSONDocOUT.JSONAddElement(iter, "19.1", "Inclusion directives should only be preceeded by other inclusion directives, pp directives or comments : "); - break; - } - else - { - break; - } - - - } - } - - HaveWeMatchIllegal191Yet = true; - } - - continue; - } - - HaveWeMatchIllegal191Yet = true; - } - - InputFile.close(); - } - } - -private: -}; -/**********************************************************************************************************************/ -class CheckForNullStatements -{ -public: - CheckForNullStatements() {} - - void Check(void) - { - bool HaveWeMatchedASemi = false; - bool ShouldBeTagged = false; - bool HaveWeSeenAComment = false; - bool WhiteSpacePostSemi = false; - - for (auto &iter : NullStmtProto) - { -#if 0 - std::cout << iter.Line << ":" << iter.Column << ":" << iter.FileName << "\n"; -#endif - - ShouldBeTagged = false; - HaveWeMatchedASemi = false; - HaveWeSeenAComment = false; - WhiteSpacePostSemi = false; - - std::ifstream InputFile(iter.FileName); - - unsigned counter = 0U; - - for (std::string line; getline(InputFile, line);) - { - counter++; - if (counter == iter.Line) - { - for (auto &iterchar : line) - { - if (iterchar == ';') - { - if (HaveWeMatchedASemi) - { - ShouldBeTagged = true; - break; - } - - HaveWeMatchedASemi = true; - continue; - } - - if (iterchar == ' ') - { - if (HaveWeMatchedASemi) - { - WhiteSpacePostSemi = true; - continue; - } - - if (WhiteSpacePostSemi) - { - ShouldBeTagged = true; - break; - } - - continue; - } - - if (iterchar == '\t') - { - - if (HaveWeMatchedASemi) - { - ShouldBeTagged = true; - break; - } - else - { - continue; - } - } - - if (iterchar == '/') - { - HaveWeSeenAComment = true; - - if (HaveWeMatchedASemi) - { - if (WhiteSpacePostSemi) - { - break; - } - else - { - ShouldBeTagged = true; - break; - } - } - else - { - ShouldBeTagged = true; - break; - } - - break; - } - - ShouldBeTagged = true; - break; - } - } - - if (ShouldBeTagged) - { - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, iter.IsInSysHeader)) - { - /*intentionally left blank*/ - } - else - { - if (Devi::IsTheMatchInMainFile(MainFileOnly, iter.IsInMainFile)) - { - std::cout << "14.3" << ":" << "Illegal NullStmt form:" << iter.FileName << ":" << iter.Line << ":" << iter.Column << ":" << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "14.3", "Illegal NullStmt form:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "14.3", "Illegal NullStmt form:"); - } - } - - break; - } - } - - InputFile.close(); - } - } - -private: -}; -/**********************************************************************************************************************/ -class onEndOfAllTUs -{ -public: onEndOfAllTUs() {} - - static void run(void) - { - /*@DEVI-start of 8.8*/ - for (auto &iter : ExternObjInfoProto) - { - if (iter.HasMoreThanOneDefinition) - { - std::cout << "8.8:" << "External function or object is defined in more than one file:"; - std::cout << iter.XObjSLStr << ":" << iter.XObjNameStr << "\n"; - - XMLDocOut.XMLAddNode(iter.LineNumber, iter.ColumnNumber, iter.FileName, "8.8", "External function or object is defined in more than one file: "); - JSONDocOUT.JSONAddElement(iter.LineNumber, iter.ColumnNumber, iter.FileName, "8.8", "External function or object is defined in more than one file: "); - } - } - /*end of 8.8*/ - - /*@DEVI-start of 5.x*/ - /*@DEVI-first we need to do some cleanup and mark some entries as invalid.*/ - for (auto &iter : IdentInfoProto) - { - if (iter.Name == "") - { - iter.IsValid = false; - } - - if (iter.NK == Devi::NodeKind::RecordDecl) - { - for (auto &yaiter : IdentInfoProto) - { - if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) - { - if ((iter.IsIncomplete != yaiter.IsIncomplete) && iter.IsValid && yaiter.IsValid) - { - iter.IsValid = false; - } - } - - if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) - { - yaiter.IsValid = false; - } - } - } - - if (iter.NK == Devi::NodeKind::FieldDecl) - { - for (auto &yaiter : IdentInfoProto) - { - if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) - { - yaiter.IsValid = false; - } - } - } - - if (iter.NK == Devi::NodeKind::ParmVarDecl) - { - for (auto &yaiter : IdentInfoProto) - { - if (iter.Name == yaiter.Name && iter.SLString == yaiter.SLString && yaiter.NK == Devi::NodeKind::VarDecl) - { - yaiter.IsValid = false; - } - } - } - - if (iter.NK == Devi::NodeKind::FunctionDecl) - { - for (auto &yaiter : IdentInfoProto) - { - if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) - { - if (iter.FDKind != yaiter.FDKind && iter.IsValid && yaiter.IsValid) - { - iter.IsValid = false; - } - } - } - } - } - - /*@DEVI-now we can start looking for things to tag*/ - for (auto &iter : IdentInfoProto) - { - if (iter.IsValid == false) - { - continue; - } - - for (auto &yaiter : IdentInfoProto) - { - if (yaiter.IsValid == false) - { - continue; - } - - if (iter.Name == yaiter.Name && iter.SLString != yaiter.SLString) - { - /*tag 5.7*/ - std::cout << "5.7:" << "Identifier re-used:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.7", "Identifier re-used:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.7", "Identifier re-used:"); - - if (iter.NK == Devi::NodeKind::TypedefDecl) - { - /*tag 5.3*/ - std::cout << "5.3:" << "Typedef identifier is not unique:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.3", "Typedef identifier is not unique:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.3", "Typedef identifier is not unique:"); - } - - if (iter.NK == Devi::NodeKind::RecordDecl) - { - /*tag 5.4*/ - std::cout << "5.4:" << "Tag identifier is not unique:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.4", "Tag identifier is not unique:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.4", "Tag identifier is not unique:"); - } - - if (iter.NK == Devi::NodeKind::RecordDecl && yaiter.NK != Devi::NodeKind::RecordDecl) - { - /*tag 5.6*/ - std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - } - - if (iter.NK == Devi::NodeKind::LabelDecl && yaiter.NK != Devi::NodeKind::LabelDecl) - { - /*tag 5.6*/ - std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - } - - if (((iter.NK != Devi::NodeKind::RecordDecl) && (iter.NK != Devi::NodeKind::LabelDecl)) && \ - ((yaiter.NK == Devi::NodeKind::RecordDecl) || (yaiter.NK == Devi::NodeKind::LabelDecl))) - { - /*tag 5.6*/ - std::cout << "5.6:" << "The Identifier is re-used in another namespace:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.6", "The Identifier is re-used in another namespace:"); - } - - if (iter.FileName == yaiter.FileName && iter.Scope == Devi::Scope::Block && yaiter.Scope == Devi::Scope::TU) - { - /*tag 5.2*/ - std::cout << "5.2:" << "This identifier is being hidden by an identifier of the same name in file scope:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.2", "This identifier is being hidden by an identifier of the same name in file scope:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.2", "This identifier is being hidden by an identifier of the same name in file scope:"); - } - - if (iter.IsStatic) - { - /*tag 5.5*/ - std::cout << "5.5:" << "Identifier with static storage duration is re-used:"; - std::cout << iter.SLString << ":" << iter.Name << ":" << yaiter.SLString << "\n"; - - XMLDocOut.XMLAddNode(iter.Line, iter.Column, iter.FileName, "5.5", "Identifier with static storage duration is re-used:"); - JSONDocOUT.JSONAddElement(iter.Line, iter.Column, iter.FileName, "5.5", "Identifier with static storage duration is re-used:"); - } - } - } - } - /*end of 5.x*/ - } - -private: -}; -/**********************************************************************************************************************/ -class MyASTConsumer : public ASTConsumer { - -public: - MyASTConsumer(Rewriter &R) : HandlerForCmpless(R), HandlerWhileCmpless(R), HandlerElseCmpless(R), HandlerIfCmpless(R), \ - HandlerForIfElse(R), HandlerForSwitchBrkLess(R), HandlerForSwitchDftLEss(R), HandlerForMCSwitch151(R), HandlerForMCSwitch155(R), \ - HandlerForMCFunction161(R), HandlerForFunction162(R), HandlerForFunction164(R), HandlerForFunction166(R), HandlerForFunction168(R), \ - HandlerForFunction169(R), HandlerForPA171(R), HandlerForSU184(R), HandlerForType6465(R), HandlerForDCDF81(R), HandlerForDCDF82(R), \ - HandlerForInit91(R), HandlerForInit92(R), HandlerForInit93(R), HandlerForExpr123(R), HandlerForExpr124(R), HandlerForExpr125(R), \ - HandlerForExpr126(R), HandlerForExpr127(R), HandlerForExpr128(R), HandlerForExpr129(R), HandlerForExpr1210(R), HandlerForExpr1213(R), \ - HandlerForCSE131(R), HandlerForCSE132(R), HandlerForCSE1332(R), HandlerForCSE134(R), HandlerForCSE136(R), HandlerForCF144(R), \ - HandlerForCF145(R), HandlerForCF146(R), HandlerForCF147(R), HandlerForCF148(R), HandlerForSwitch154(R), HandlerForPTC111(R), \ - HandlerForCSE137(R), HandlerForDCDF810(R), HandlerForFunction165(R), HandlerForFunction1652(R), HandlerForPointer171(R), \ - HandlerForPointer1723(R), HandlerForPointer174(R), HandlerForPointer175(R), HandlerForTypes61(R), HandlerForSU181(R), \ - HandlerForMCPTCCSTYLE(R), HandlerForATC101(R), HandlerForIdent51(R), HandlerForDCDF87(R), HandlerForDCDF88(R), HandlerForLangX23(R), \ - HandlerForFunction167(R), HandlerForCF143(R), HandlerForExpr1212(R), HandlerForExpr1211(R), HandlerForAtc105(R), HandlerForCSE135(R), \ - HandlerForTypes612(R), HandlerForConst71(R), HandlerForIdent5X(R), HandlerForSFCPPARR01(R), HandlerForSFCPPARR02(R), \ - HandlerForSFCPPPNTR01(R), HandlerForSFCPPPNTR02(R) - { - -/*@DEVI-disables all matchers*/ -#if defined(_MUT0_EN_MATCHERS) - - Matcher.addMatcher(forStmt(unless(hasDescendant(compoundStmt()))).bind("mcfor"), &HandlerForCmpless); - - Matcher.addMatcher(whileStmt(unless(hasDescendant(compoundStmt()))).bind("mcwhile"), &HandlerWhileCmpless); - - Matcher.addMatcher(ifStmt(allOf(hasElse(unless(ifStmt())), hasElse(unless(compoundStmt())))).bind("mcelse"), &HandlerElseCmpless); - - Matcher.addMatcher(ifStmt(unless(hasDescendant(compoundStmt()))).bind("mcif"), &HandlerIfCmpless); - - Matcher.addMatcher(ifStmt(allOf(hasElse(ifStmt()), unless(hasAncestor(ifStmt())), unless(hasDescendant(ifStmt(hasElse(unless(ifStmt()))))))).bind("mcifelse"), &HandlerForIfElse); - - Matcher.addMatcher(switchStmt(hasDescendant(compoundStmt(hasDescendant(switchCase(unless(hasDescendant(breakStmt()))))))).bind("mcswitchbrk"), &HandlerForSwitchBrkLess); - - Matcher.addMatcher(switchStmt(unless(hasDescendant(defaultStmt()))).bind("mcswitchdft"), &HandlerForSwitchDftLEss); - - if (umRuleList.at("15.1")) - { - Matcher.addMatcher(switchStmt(forEachDescendant(caseStmt(hasAncestor(compoundStmt().bind("mccmp151"))).bind("mccase151"))), &HandlerForMCSwitch151); - } - - if (umRuleList.at("15.5")) - { - Matcher.addMatcher(switchStmt(unless(hasDescendant(caseStmt()))).bind("mcswitch155"), &HandlerForMCSwitch155); - } - - if (umRuleList.at("16.1")) - { - Matcher.addMatcher(functionDecl().bind("mcfunction161"), &HandlerForMCFunction161); - } - - if (umRuleList.at("16.2")) - { - Matcher.addMatcher(functionDecl(forEachDescendant(callExpr().bind("mc162callexpr"))).bind("mc162funcdec"), &HandlerForFunction162); - } - - if (umRuleList.at("16.4")) - { - Matcher.addMatcher(functionDecl().bind("mcfunc164"), &HandlerForFunction164); - } - - if (umRuleList.at("16.6")) - { - Matcher.addMatcher(callExpr().bind("mcfunc166"), &HandlerForFunction166); - } - - if (umRuleList.at("16.8")) - { - Matcher.addMatcher(functionDecl(forEachDescendant(returnStmt().bind("mcfunc168"))), &HandlerForFunction168); - } - - if (umRuleList.at("16.9")) - { - Matcher.addMatcher(implicitCastExpr(unless(hasAncestor(callExpr()))).bind("mcfunc169"), &HandlerForFunction169); - } - - if (umRuleList.at("17.1")) - { - Matcher.addMatcher(varDecl().bind("mcpa171"), &HandlerForPA171); - } - - if (umRuleList.at("18.4")) - { - Matcher.addMatcher(recordDecl(isUnion()).bind("mcsu184"), &HandlerForSU184); - } - - if (umRuleList.at("6.4") || umRuleList.at("6.5")) - { - Matcher.addMatcher(fieldDecl(isBitField()).bind("mctype6465"), &HandlerForType6465); - } - - if (umRuleList.at("8.1")) - { - Matcher.addMatcher(functionDecl().bind("mcdcdf81"), &HandlerForDCDF81); - } - - if (umRuleList.at("8.2")) - { - Matcher.addMatcher(varDecl().bind("mcdcdf82"), &HandlerForDCDF82); - } - - if (umRuleList.at("9.1")) - { - Matcher.addMatcher(varDecl().bind("mcinit91"), &HandlerForInit91); - } - - if (umRuleList.at("9.2")) - { - Matcher.addMatcher(initListExpr(hasAncestor(varDecl().bind("mcinit92daddy"))).bind("mcinit92"), &HandlerForInit92); - } - - if (umRuleList.at("9.3")) - { - Matcher.addMatcher(enumConstantDecl(anyOf(allOf(hasDescendant(integerLiteral().bind("mcinit93kiddy")), \ - hasAncestor(enumDecl().bind("mcinit93daddy"))), hasAncestor(enumDecl().bind("mcinit93daddy")))).bind("mcinit93"), &HandlerForInit93); - } - - if (umRuleList.at("12.3")) - { - Matcher.addMatcher(unaryExprOrTypeTraitExpr(hasDescendant(expr().bind("mcexpr123kiddy"))).bind("mcexpr123"), &HandlerForExpr123); - } - - if (umRuleList.at("12.4")) - { - Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), hasRHS(expr().bind("mcexpr124")))), &HandlerForExpr124); - } - - if (umRuleList.at("12.5")) - { - Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), \ - eachOf(hasRHS(allOf(expr().bind("lrhs"), unless(anyOf(implicitCastExpr() , declRefExpr(), callExpr(), floatLiteral(), integerLiteral(), stringLiteral()))))\ - , hasLHS(allOf(expr().bind("lrhs"), unless(anyOf(implicitCastExpr(), declRefExpr(), callExpr(), floatLiteral(), integerLiteral(), stringLiteral())))))))\ - , &HandlerForExpr125); - } - - if (umRuleList.at("12.6")) - { - Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("||"), hasOperatorName("&&")), \ - eachOf(hasLHS(expr().bind("mcexpr126rl")), hasRHS(expr().bind("mcexpr126rl"))))), &HandlerForExpr126); - } - - if (umRuleList.at("12.7")) - { - Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName("<<"), hasOperatorName(">>"), hasOperatorName("~"), hasOperatorName("<<="), \ - hasOperatorName(">>="), hasOperatorName("&"), hasOperatorName("&="), hasOperatorName("^"), hasOperatorName("^=")\ - , hasOperatorName("|"), hasOperatorName("|=")), eachOf(hasLHS(expr().bind("mcexpr127rl")), hasRHS(expr().bind("mcexpr127rl"))))), &HandlerForExpr127); - } - - if (umRuleList.at("12.8")) - { - Matcher.addMatcher(binaryOperator(allOf(eachOf(hasOperatorName(">>"), hasOperatorName(">>="), hasOperatorName("<<="), hasOperatorName("<<")), \ - hasLHS(expr().bind("mcexpr128lhs")) , hasRHS(expr().bind("mcexpr128rhs")))), &HandlerForExpr128); - } - - if (umRuleList.at("12.9")) - { - Matcher.addMatcher(unaryOperator(allOf(hasOperatorName("-"), hasUnaryOperand(expr().bind("mcexpr129")))), &HandlerForExpr129); - } - - if (umRuleList.at("12.10")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(","), hasLHS(expr().bind("mcexpr1210")))), &HandlerForExpr1210); - } - - if (umRuleList.at("12.13")) - { - Matcher.addMatcher(unaryOperator(allOf(eachOf(hasOperatorName("++"), hasOperatorName("--"))\ - , anyOf(hasAncestor(binaryOperator()), hasDescendant(binaryOperator())))).bind("mcexpr1213"), &HandlerForExpr1213); - } - - if (umRuleList.at("13.1")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("="), eachOf(hasLHS(expr().bind("cse131rlhs")), hasRHS(expr().bind("cse131rlhs"))))), &HandlerForCSE131); - } - - if (umRuleList.at("13.2")) - { - Matcher.addMatcher(ifStmt(hasCondition(expr(unless(hasDescendant(binaryOperator(anyOf(hasOperatorName("<")\ - , hasOperatorName(">"), hasOperatorName("=="), hasOperatorName("<="), hasOperatorName(">=")))))).bind("mccse132"))), &HandlerForCSE132); - } - - if (umRuleList.at("13.3")) - { - Matcher.addMatcher(binaryOperator(allOf(anyOf(hasOperatorName("<"), hasOperatorName(">"), hasOperatorName("<="), hasOperatorName(">="), hasOperatorName("==")), \ - eachOf(hasLHS(expr().bind("mccse1332rl")), hasRHS(expr().bind("mccse1332rl"))))).bind("mccse1332daddy"), &HandlerForCSE1332); - } - - if (umRuleList.at("13.4")) - { - Matcher.addMatcher(forStmt().bind("mccse134"), &HandlerForCSE134); - } - - if (umRuleList.at("13.6")) - { - Matcher.addMatcher(forStmt(forEachDescendant(stmt(eachOf(unaryOperator(allOf(anyOf(hasOperatorName("++"), hasOperatorName("--")), hasUnaryOperand(declRefExpr().bind("mccse136kiddo")))), \ - binaryOperator(allOf(hasOperatorName("="), hasLHS(declRefExpr().bind("mccse136kiddo")))))))).bind("mccse136daddy"), &HandlerForCSE136); - } - - if (umRuleList.at("14.4")) - { - Matcher.addMatcher(gotoStmt().bind("mccf144"), &HandlerForCF144); - } - - if (umRuleList.at("14.5")) - { - Matcher.addMatcher(continueStmt().bind("mccf145"), &HandlerForCF145); - } - - if (umRuleList.at("14.6")) - { - Matcher.addMatcher(breakStmt(hasAncestor(stmt(anyOf(forStmt().bind("mccffofo"), doStmt().bind("mccfdodo"), whileStmt().bind("mccfwuwu"))))), &HandlerForCF146); - } - - if (umRuleList.at("14.7")) - { - Matcher.addMatcher(returnStmt(hasAncestor(functionDecl().bind("mccf147"))), &HandlerForCF147); - } - - if (umRuleList.at("14.8")) - { - Matcher.addMatcher(forStmt(unless(has(compoundStmt()))).bind("mccf148for"), &HandlerForCF148); - } - - if (umRuleList.at("14.8")) - { - Matcher.addMatcher(whileStmt(unless(has(compoundStmt()))).bind("mccf148while"), &HandlerForCF148); - } - - if (umRuleList.at("14.8")) - { - Matcher.addMatcher(doStmt(unless(has(compoundStmt()))).bind("mccf148do"), &HandlerForCF148); - } - - if (umRuleList.at("14.8")) - { - Matcher.addMatcher(switchStmt(unless(has(compoundStmt()))).bind("mccf148switch"), &HandlerForCF148); - } - - if (umRuleList.at("15.4")) - { - Matcher.addMatcher(switchStmt(hasCondition(expr().bind("mcswitch154"))).bind("mcswitch154daddy"), &HandlerForSwitch154); - } - - if (umRuleList.at("11.1")) - { - Matcher.addMatcher(implicitCastExpr().bind("mcptc111"), &HandlerForPTC111); - } - - if (umRuleList.at("13.7")) - { - Matcher.addMatcher(expr().bind("mccse137"), &HandlerForCSE137); - } - - if (umRuleList.at("8.10")) - { - Matcher.addMatcher(callExpr(hasAncestor(functionDecl().bind("mcdcdf810daddy"))).bind("mcdcdf810"), &HandlerForDCDF810); - } - - if (umRuleList.at("16.5")) - { - Matcher.addMatcher(functionDecl(allOf(returns(anything()), unless(returns(asString("void"))), hasBody(compoundStmt()) \ - , unless(hasDescendant(returnStmt())))).bind("mcfunction165"), &HandlerForFunction165); - } - - if (umRuleList.at("16.5")) - { - Matcher.addMatcher(functionDecl(allOf(parameterCountIs(0), hasBody(compoundStmt()))).bind("mcfunction1652"), &HandlerForFunction1652); - } - - if (umRuleList.at("17.1")) - { - Matcher.addMatcher(declRefExpr(allOf(to(varDecl().bind("loco")), unless(hasParent(castExpr(hasCastKind(clang::CK_ArrayToPointerDecay)))), \ - hasAncestor(stmt(eachOf(binaryOperator(hasOperatorName("+")).bind("bino"), \ - binaryOperator(hasOperatorName("-")).bind("bino"), unaryOperator(hasOperatorName("++")).bind("uno"), \ - unaryOperator(hasOperatorName("--")).bind("uno"), binaryOperator(hasOperatorName("/")).bind("bino"), \ - binaryOperator(hasOperatorName("*")).bind("bino"), binaryOperator(hasOperatorName("<")).bind("bino"), \ - binaryOperator(hasOperatorName("<=")).bind("bino"), binaryOperator(hasOperatorName(">")).bind("bino"), \ - binaryOperator(hasOperatorName(">=")).bind("bino")))))).bind("mcpointer171"), &HandlerForPointer171); - } - - /*start of 17.3 matchers*/ - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("<="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("<"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(">="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName(">"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("-"), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - - if (umRuleList.at("17.2") || umRuleList.at("17.3")) - { - Matcher.addMatcher(binaryOperator(allOf(hasOperatorName("-="), hasRHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723rhs"))))), \ - hasLHS(expr(anyOf(hasDescendant(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs")), \ - has(declRefExpr(hasType(pointerType())).bind("mcpointer1723lhs"))))))).bind("mcpointer1723daddy"), &HandlerForPointer1723); - } - /*end of 17.3 matchers*/ - - /*start of 17.4 matchers*/ - if (umRuleList.at("17.4")) - { - Matcher.addMatcher(castExpr(allOf(hasCastKind(CK_ArrayToPointerDecay), unless(hasParent(arraySubscriptExpr())))).bind("mcpointer174"), &HandlerForPointer174); - } - - if (umRuleList.at("17.4")) - { - Matcher.addMatcher(declRefExpr(allOf(hasAncestor(expr(anyOf(binaryOperator(hasOperatorName("-=")), \ - unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), \ - binaryOperator(hasOperatorName("+")), binaryOperator(hasOperatorName("+=")), \ - binaryOperator(hasOperatorName("-"))))), to(varDecl(hasType(pointerType()))))).bind("mcpointer1742"), &HandlerForPointer174); - } - /*end of 17.4 matchers*/ - - if (umRuleList.at("17.5")) - { - Matcher.addMatcher(varDecl(hasType(pointerType())).bind("mcpointer175"), &HandlerForPointer175); - } - - if (umRuleList.at("17.5")) - { - Matcher.addMatcher(fieldDecl().bind("mcpointer175field"), &HandlerForPointer175); - } - - if (umRuleList.at("6.1")) - { - Matcher.addMatcher(declRefExpr(allOf(to(varDecl().bind("mctypes6origin")), \ - hasAncestor(binaryOperator(allOf(hasRHS(expr().bind("mctypes6rhs")), \ - hasOperatorName("="))).bind("mctypes6dous")), hasType(isAnyCharacter()))), &HandlerForTypes61); - } - - if (umRuleList.at("18.1")) - { - Matcher.addMatcher(varDecl(hasType(incompleteArrayType())).bind("mcsu181arr"), &HandlerForSU181); - } - - if (umRuleList.at("18.1")) - { - Matcher.addMatcher(recordDecl(isStruct()).bind("mcsu181struct"), &HandlerForSU184); - } - - Matcher.addMatcher(cStyleCastExpr().bind("mcptc11cstyle"), &HandlerForMCPTCCSTYLE); - - if (umRuleList.at("10.1")) - { - Matcher.addMatcher(implicitCastExpr(has(expr(anyOf(binaryOperator().bind("atcdous"), unaryOperator().bind("atcuno"), \ - parenExpr().bind("atcparens"), implicitCastExpr().bind("atckidice"), \ - cStyleCastExpr().bind("atccstyle"))))).bind("atcdaddy"), &HandlerForATC101); - } - - if (umRuleList.at("5.1")) - { - Matcher.addMatcher(namedDecl().bind("ident5nameddecl"), &HandlerForIdent51); - } - - if (umRuleList.at("8.7")) - { - Matcher.addMatcher(declRefExpr(allOf(hasAncestor(functionDecl().bind("mcdcdf87daddy")), \ - to(varDecl(unless(hasAncestor(functionDecl()))).bind("mcdcdf87origin")))).bind("mcdcdfobj"), &HandlerForDCDF87); - } - -/*@DEVI-these two matcheres are breaking our 3.9 backwards compatibility.*/ -#if 1 - if (umRuleList.at("8.8")) - { - Matcher.addMatcher(functionDecl(hasExternalFormalLinkage()).bind("mcdcdf88function"), &HandlerForDCDF88); - } - - if (umRuleList.at("8.8")) - { - Matcher.addMatcher(varDecl(hasExternalFormalLinkage()).bind("mcdcdf88var"), &HandlerForDCDF88); - } -#endif - - if (umRuleList.at("2.3")) - { - Matcher.addMatcher(expr().bind("mclangx23"), &HandlerForLangX23); - } - - if (umRuleList.at("16.7")) - { - Matcher.addMatcher(parmVarDecl(unless(allOf(hasAncestor(functionDecl(hasDescendant(binaryOperator(allOf(hasOperatorName("="), \ - hasLHS(hasDescendant(declRefExpr(allOf(hasAncestor(unaryOperator(hasOperatorName("*"))), \ - to(parmVarDecl(hasType(pointerType())).bind("zulu"))))))))))), equalsBoundNode("zulu")))).bind("mcfunction167"), &HandlerForFunction167); - } - - if (umRuleList.at("14.3")) - { - Matcher.addMatcher(nullStmt().bind("mccf143nullstmt"), &HandlerForCF143); - } - - if (umRuleList.at("12.12")) - { - Matcher.addMatcher(recordDecl(allOf(has(fieldDecl(hasType(realFloatingPointType()))), isUnion())).bind("mcexpr1212"), &HandlerForExpr1212); - } - - if (umRuleList.at("12.11")) - { - Matcher.addMatcher(expr(hasDescendant(expr(anyOf(unaryOperator(hasOperatorName("--"), hasOperatorName("++")).bind("mcexpr1211uno"), \ - binaryOperator(anyOf(hasOperatorName("*"), hasOperatorName("/"), \ - hasOperatorName("-"), hasOperatorName("+"))).bind("mcexpr1211dous"))))).bind("mcexpr1211"), &HandlerForExpr1211); - } - - if (umRuleList.at("10.5")) - { - Matcher.addMatcher(binaryOperator(allOf(hasLHS(expr(hasType(isInteger())).bind("mcatc105lhs")), hasOperatorName("<<"))).bind("mcatc105"), &HandlerForAtc105); - } - - if (umRuleList.at("10.5")) - { - Matcher.addMatcher(unaryOperator(allOf(hasOperatorName("~") , hasUnaryOperand(expr(hasType(isInteger())).bind("mcatc105lhs")))).bind("mcatc105uno"), &HandlerForAtc105); - } - - if (umRuleList.at("13.5")) - { - Matcher.addMatcher(forStmt().bind("mccse135"), &HandlerForCSE135); - } - - if (umRuleList.at("6.1") || umRuleList.at("6.2")) - { - Matcher.addMatcher(binaryOperator(allOf(hasRHS(expr(has(expr(anyOf(integerLiteral().bind("mc612intlit"), \ - characterLiteral().bind("mc612charlit")))))), hasLHS(expr(hasType(isAnyCharacter())).bind("mc612exp")), \ - hasOperatorName("="))), &HandlerForTypes612); - } - - /*@DEVI-start of 7.1 matchers.*/ - if (umRuleList.at("7.1")) - { - Matcher.addMatcher(stringLiteral().bind("mcconst71string"), &HandlerForConst71); - } - - if (umRuleList.at("7.1")) - { - Matcher.addMatcher(characterLiteral().bind("mcconst71char"), &HandlerForConst71); - } - - if (umRuleList.at("7.1")) - { - Matcher.addMatcher(integerLiteral().bind("mcconst71int"), &HandlerForConst71); - } - /*end of 7.1*/ - - /*@DEVI-matchers for 5.x*/ - /*@DEVI-typedefs always have file scope.*/ - if (umRuleList.at("5.1") || umRuleList.at("5.2"), umRuleList.at("5.3") || umRuleList.at("5.4") || umRuleList.at("5.5") || umRuleList.at("5.6") || umRuleList.at("5.7")) - { - Matcher.addMatcher(typedefDecl().bind("ident5typedef"), &HandlerForIdent5X); - } - -#if 0 - Matcher.addMatcher(typedefDecl(unless(hasAncestor(functionDecl()))).bind("ident5typedef"), &HandlerForIdent5X); - - Matcher.addMatcher(typedefDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5typedef"), &HandlerForIdent5X); -#endif - - - if (umRuleList.at("5.1") || umRuleList.at("5.2"), umRuleList.at("5.3") || umRuleList.at("5.4") || umRuleList.at("5.5") || umRuleList.at("5.6") || umRuleList.at("5.7")) - { - Matcher.addMatcher(recordDecl(unless(hasAncestor(functionDecl()))).bind("ident5record"), &HandlerForIdent5X); - - Matcher.addMatcher(recordDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5record"), &HandlerForIdent5X); - - Matcher.addMatcher(fieldDecl(unless(hasAncestor(functionDecl()))).bind("ident5field"), &HandlerForIdent5X); - - Matcher.addMatcher(fieldDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5field"), &HandlerForIdent5X); - - Matcher.addMatcher(parmVarDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5parmvar"), &HandlerForIdent5X); - - Matcher.addMatcher(functionDecl().bind("ident5func"), &HandlerForIdent5X); - - Matcher.addMatcher(varDecl(unless(hasAncestor(functionDecl()))).bind("ident5var"), &HandlerForIdent5X); - - Matcher.addMatcher(varDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5var"), &HandlerForIdent5X); - - Matcher.addMatcher(enumDecl(unless(hasAncestor(functionDecl()))).bind("ident5enum") , &HandlerForIdent5X); - - Matcher.addMatcher(enumDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5enum"), &HandlerForIdent5X); - - /*@DEVI-labels always have function scope.*/ - Matcher.addMatcher(labelDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5label"), &HandlerForIdent5X); - - Matcher.addMatcher(enumConstantDecl(unless(hasAncestor(functionDecl()))).bind("ident5enumconst"), &HandlerForIdent5X); - - Matcher.addMatcher(enumConstantDecl(hasAncestor(functionDecl().bind("id5funcscope"))).bind("ident5enumconst"), &HandlerForIdent5X); - } - /*end of matchers for 5.x*/ - - /*start of SaferCPP matchers*/ - Matcher.addMatcher(varDecl(hasType(arrayType())).bind("sfcpparrdecl"), &HandlerForSFCPPARR01); - - Matcher.addMatcher(fieldDecl(hasType(arrayType())).bind("sfcpparrfield"), &HandlerForSFCPPARR01); - - Matcher.addMatcher(implicitCastExpr(hasCastKind(CK_ArrayToPointerDecay)).bind("sfcpparrcastexpr"), &HandlerForSFCPPARR01); - - Matcher.addMatcher(cStyleCastExpr(hasCastKind(CK_ArrayToPointerDecay)).bind("sfcpparrcastexpr"), &HandlerForSFCPPARR01); - - Matcher.addMatcher(declRefExpr(hasAncestor(binaryOperator(allOf(hasLHS(declRefExpr().bind("sfcpparrdeep")), hasRHS(hasDescendant(implicitCastExpr(hasCastKind(CK_ArrayToPointerDecay))))\ - , hasOperatorName("="))))), &HandlerForSFCPPARR02); - - Matcher.addMatcher(varDecl(hasType(pointerType())).bind("sfcpppntr01"), &HandlerForSFCPPPNTR01); - - Matcher.addMatcher(declRefExpr(hasType(pointerType())).bind("sfcpppntr02"), &HandlerForSFCPPPNTR02); - /*end of SaferCPP matchers*/ - -#endif - } - - void HandleTranslationUnit(ASTContext &Context) override { - Matcher.matchAST(Context); - } - -private: - MCForCmpless HandlerForCmpless; - MCWhileCmpless HandlerWhileCmpless; - MCElseCmpless HandlerElseCmpless; - MCIfCmpless HandlerIfCmpless; - IfElseMissingFixer HandlerForIfElse; - MCSwitchBrkless HandlerForSwitchBrkLess; - MCSwitchDftLess HandlerForSwitchDftLEss; - MCSwitch151 HandlerForMCSwitch151; - MCSwitch155 HandlerForMCSwitch155; - MCFunction161 HandlerForMCFunction161; - MCFunction162 HandlerForFunction162; - MCFunction164 HandlerForFunction164; - MCFunction166 HandlerForFunction166; - MCFunction168 HandlerForFunction168; - MCFunction169 HandlerForFunction169; - MCPA171 HandlerForPA171; - MCSU184 HandlerForSU184; - MCTypes6465 HandlerForType6465; - MCDCDF81 HandlerForDCDF81; - MCDCDF82 HandlerForDCDF82; - MCInit91 HandlerForInit91; - MCInit92 HandlerForInit92; - MCInit93 HandlerForInit93; - MCExpr123 HandlerForExpr123; - MCExpr124 HandlerForExpr124; - MCExpr125 HandlerForExpr125; - MCExpr126 HandlerForExpr126; - MCExpr127 HandlerForExpr127; - MCExpr128 HandlerForExpr128; - MCExpr129 HandlerForExpr129; - MCExpr1210 HandlerForExpr1210; - MCExpr1213 HandlerForExpr1213; - MCCSE131 HandlerForCSE131; - MCCSE132 HandlerForCSE132; - MCCSE1332 HandlerForCSE1332; - MCCSE134 HandlerForCSE134; - MCCSE136 HandlerForCSE136; - MCCF144 HandlerForCF144; - MCCF145 HandlerForCF145; - MCCF146 HandlerForCF146; - MCCF147 HandlerForCF147; - MCCF148 HandlerForCF148; - MCSwitch154 HandlerForSwitch154; - MCPTC111 HandlerForPTC111; - MCCSE137 HandlerForCSE137; - MCDCDF810 HandlerForDCDF810; - MCFunction165 HandlerForFunction165; - MCFunction1652 HandlerForFunction1652; - MCPointer171 HandlerForPointer171; - MCPointer1723 HandlerForPointer1723; - MCPointer174 HandlerForPointer174; - MCPointer175 HandlerForPointer175; - MCTypes61 HandlerForTypes61; - MCSU181 HandlerForSU181; - MCPTC11CSTYLE HandlerForMCPTCCSTYLE; - MCATC101 HandlerForATC101; - MCIdent51 HandlerForIdent51; - MCDCDF87 HandlerForDCDF87; - MCDCDF88 HandlerForDCDF88; - MCLangX23 HandlerForLangX23; - MCFunction167 HandlerForFunction167; - MCCF143 HandlerForCF143; - MCExpr1212 HandlerForExpr1212; - MCExpr1211 HandlerForExpr1211; - MCATC105 HandlerForAtc105; - MCCSE135 HandlerForCSE135; - MCTypes612 HandlerForTypes612; - MCConst71 HandlerForConst71; - MCIdent5x HandlerForIdent5X; - SFCPPARR01 HandlerForSFCPPARR01; - SFCPPARR02 HandlerForSFCPPARR02; - SFCPPPNTR01 HandlerForSFCPPPNTR01; - SFCPPPNTR02 HandlerForSFCPPPNTR02; - MatchFinder Matcher; -}; -/**********************************************************************************************************************/ -class Mutator0DiagnosticConsumer : public clang::DiagnosticConsumer -{ -public: - - virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override - { - DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); - - SourceLocation SL = Info.getLocation(); - CheckSLValidity(SL); - - SourceManager &SM = Info.getSourceManager(); - - if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, SM, SL)) - { - return void(); - } - - if (!Devi::IsTheMatchInMainFile(MainFileOnly, SM, SL)) - { - return void(); - } - - SL = SM.getSpellingLoc(SL); - - unsigned SpellingLine = SM.getSpellingLineNumber(SL); - unsigned SpellingColumn = SM.getSpellingColumnNumber(SL); - std::string FileName = SM.getFilename(SL).str(); - - SmallString<100> DiagBuffer; - - Info.FormatDiagnostic(DiagBuffer); - -#if 0 - std::cout << "ClangDiag:" << DiagBuffer.str().str() << ":" << SL.printToString(SM) << ":" << Info.getID() << ":" << "\n"; -#endif - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "ClangDiag", DiagBuffer.str().str()); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "ClangDiag", DiagBuffer.str().str()); - - if (Info.getID() == 872U) - { - std::cout << "2.2:" << "Illegal comment format(/*...*/) used:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "2.2", "Illegal comment format(/*...*/) used:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "2.2", "Illegal comment format(/*...*/) used:"); - } - - if (Info.getID() == 974U) - { - std::cout << "2.3:" << "Use of the character sequence /* inside a comment is illegal:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "2.3", "Use of the character sequence /* inside a comment is illegal:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "2.3", "Use of the character sequence /* inside a comment is illegal:"); - } - - if (Info.getID() == 938U) - { - std::cout << "4.2:" << "Use of trigraphs is illegal:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "4.2", "Use of trigraphs is illegal:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "4.2", "Use of trigraphs is illegal:"); - } - - if (Info.getID() == 4578U) - { - std::cout << "9.2:" << "Brace initialization has either not been correctly used or not used at all:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "9.2", "Brace initialization has either not been correctly used or not used at all:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "9.2", "Brace initialization has either not been correctly used or not used at all:"); - } - - if (Info.getID() == 4872U) - { - std::cout << "14.2:" << "Expression result is unused:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "14.2", "Expression result is unused:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "14.2", "Expression result is unused:"); - } - - if (Info.getID() == 966U) - { - std::cout << "19.14:" << "\"defined\" has undefined behaviour:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "19.14", "\"defined\" has undefined behaviour:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "19.14", "\"defined\" has undefined behaviour:"); - } - - if (Info.getID() == 895U) - { - std::cout << "20.1:" << "Redefining built-in macro:" << SL.printToString(SM) << ":" << "\n"; - - XMLDocOut.XMLAddNode(SpellingLine, SpellingColumn, FileName, "20.1", "Redefining built-in macro:"); - JSONDocOUT.JSONAddElement(SpellingLine, SpellingColumn, FileName, "20.1", "Redefining built-in macro:"); - } - - } - -private: - -}; -/**********************************************************************************************************************/ -class MyFrontendAction : public ASTFrontendAction -{ -public: - MyFrontendAction() {} - - void EndSourceFileAction() override - { - - } - - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override - { -#if 1 - CI.getPreprocessor().addPPCallbacks(llvm::make_unique(&CI.getSourceManager())); -#endif - - DiagnosticsEngine &DiagEngine = CI.getPreprocessor().getDiagnostics(); - -#if 1 - Mutator0DiagnosticConsumer* M0DiagConsumer = new Mutator0DiagnosticConsumer; - - DiagEngine.setClient(M0DiagConsumer, true); -#endif - - TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); - return llvm::make_unique(TheRewriter); - } - -private: - Rewriter TheRewriter; -}; -/**********************************************************************************************************************/ -/*Main*/ -int main(int argc, const char **argv) -{ - CommonOptionsParser op(argc, argv, MutatorLVL0Cat); - - CompilationDatabase &CDB [[maybe_unused]] = op.getCompilations(); - std::vector ComCom = CDB.getAllCompileCommands(); - std::vector> ExecCL; - -#if defined(_MUT0_TEST) - for (auto &iter : ComCom) - { - ExecCL.push_back(iter.CommandLine); - } - - for (auto &iter : ExecCL) - { - for (auto &yaiter : iter) - { - std::cout << "comcom: " << yaiter << "\n"; - } - - std::cout << "\n"; - } -#endif - - const std::vector &SourcePathList = op.getSourcePathList(); - - ClangTool Tool(op.getCompilations(), op.getSourcePathList()); - - StringOptionsParser SOPProto; - - SOPProto.MC2Parser(); - -#if defined(_MUT0_TEST) - SOPProto.Dump(true); -#endif - -#if defined(_MUT0_TEST) - if (SOPProto.MC2Parser()) - { - typedef std::multimap::iterator Iter; - for (Iter iter = MC1EquivalencyMap.begin(), iterE = MC1EquivalencyMap.end(); iter != iterE; ++iter) - { - std::cout << "Key: " << iter->first << " " << "Value: " << iter->second << "\n"; - } - } -#endif - - XMLDocOut.XMLCreateReport(); - - JSONDocOUT.JSONCreateReport(); - - IsThereJunkPreInclusion ITJPIInstance; - - ITJPIInstance.Check(SourcePathList); - - int RunResult = 0; - - try - { - RunResult = Tool.run(newFrontendActionFactory().get()); - } - catch (MutExHeaderNotFound &E1) - { - std::cerr << E1.what() << "\n"; - } - catch (std::domain_error &E2) - { - std::cerr << E2.what() << "\n"; - } - catch(...) - { - std::cerr << "Unexpected exception!\n"; - } - - CheckForNullStatements CheckForNull; - - CheckForNull.Check(); - - onEndOfAllTUs::run(); - - XMLDocOut.SaveReport(); - - JSONDocOUT.CloseReport(); - - ME.DumpAll(); - ME.XMLReportAncestry(); - - return RunResult; -} //end of main -/*last line intentionally left blank.*/ - diff --git a/mutator-lvl0.h b/mutator-lvl0.h deleted file mode 100644 index c1e452a..0000000 --- a/mutator-lvl0.h +++ /dev/null @@ -1,542 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ -/**********************************************************************************************************************/ -/*inclusion guard*/ -#ifndef MUTATOR_0_H -#define MUTATOR_0_H -/**********************************************************************************************************************/ -/*included modules*/ -/*project headers*/ -#include "mutator_report.h" -/*standard library headers*/ -#include -#include -#include -#include -#include -#include -/*clang headers*/ -#include "clang/AST/ASTContext.h" -#include "clang/AST/ASTTypeTraits.h" -/**********************************************************************************************************************/ -/*externals*/ -/**********************************************************************************************************************/ -struct WeakPoint -{ - WeakPoint(std::string __psft, std::string __file, unsigned int __ln, unsigned int __cn) - { - PlaceHolderStringForType = __psft; - File = __file; - LineNumber = __ln; - ColumnNumber = __cn; - } - - std::string PlaceHolderStringForType; - std::string File; - unsigned int LineNumber; - unsigned int ColumnNumber; -}; -/**********************************************************************************************************************/ -std::map MC2OptsMap = { - {"1.1", false}, - {"1.2", false}, - {"1.3", false}, - {"1.4", false}, - {"1.5", false}, - {"2.1", false}, - {"2.2", false}, - {"2.3", false}, - {"2.4", false}, - {"3.1", false}, - {"3.2", false}, - {"3.3", false}, - {"3.4", false}, - {"3.5", false}, - {"3.6", false}, - {"4.1", false}, - {"4.2", false}, - {"5.1", false}, - {"5.2", false}, - {"5.3", false}, - {"5.4", false}, - {"5.5", false}, - {"5.6", false}, - {"5.7", false}, - {"6.1", false}, - {"6.2", false}, - {"6.3", false}, - {"6.4", false}, - {"6.5", false}, - {"7.1", false}, - {"8.1", false}, - {"8.2", false}, - {"8.3", false}, - {"8.4", false}, - {"8.5", false}, - {"8.6", false}, - {"8.7", false}, - {"8.8", false}, - {"8.9", false}, - {"8.10", false}, - {"8.11", false}, - {"8.12", false}, - {"9.1", false}, - {"9.2", false}, - {"9.3", false}, - {"10.1", false}, - {"10.2", false}, - {"10.3", false}, - {"10.4", false}, - {"10.5", false}, - {"10.6", false}, - {"11.1", false}, - {"11.2", false}, - {"11.3", false}, - {"11.4", false}, - {"11.5", false}, - {"12.1", false}, - {"12.2", false}, - {"12.3", false}, - {"12.4", false}, - {"12.5", false}, - {"12.6", false}, - {"12.7", false}, - {"12.8", false}, - {"12.9", false}, - {"12.10", false}, - {"12.11", false}, - {"12.12", false}, - {"12.13", false}, - {"13.1", false}, - {"13.2", false}, - {"13.3", false}, - {"13.4", false}, - {"13.5", false}, - {"13.6", false}, - {"13.7", false}, - {"14.1", false}, - {"14.2", false}, - {"14.3", false}, - {"14.4", false}, - {"14.5", false}, - {"14.6", false}, - {"14.7", false}, - {"14.8", false}, - {"14.9", false}, - {"14.10", false}, - {"15.0", false}, - {"15.1", false}, - {"15.2", false}, - {"15.3", false}, - {"15.4", false}, - {"15.5", false}, - {"16.1", false}, - {"16.2", false}, - {"16.3", false}, - {"16.4", false}, - {"16.5", false}, - {"16.6", false}, - {"16.7", false}, - {"16.8", false}, - {"16.9", false}, - {"16.10", false}, - {"17.1", false}, - {"17.2", false}, - {"17.3", false}, - {"17.4", false}, - {"17.5", false}, - {"17.6", false}, - {"18.1", false}, - {"18.2", false}, - {"18.3", false}, - {"18.4", false}, - {"19.1", false}, - {"19.2", false}, - {"19.3", false}, - {"19.4", false}, - {"19.5", false}, - {"19.6", false}, - {"19.7", false}, - {"19.8", false}, - {"19.9", false}, - {"19.10", false}, - {"19.11", false}, - {"19.12", false}, - {"19.13", false}, - {"19.14", false}, - {"19.15", false}, - {"19.16", false}, - {"19.17", false}, - {"20.1", false}, - {"20.2", false}, - {"20.3", false}, - {"20.4", false}, - {"20.5", false}, - {"20.6", false}, - {"20.7", false}, - {"20.8", false}, - {"20.9", false}, - {"20.10", false}, - {"20.11", false}, - {"20.12", false}, - {"21.1", false} -}; - -std::multimap MC1EquivalencyMap = { - {"1","1.1"}, - {"1","1.2"}, - {"1","2.2"}, - {"1","3.1"}, - {"2","1.3"}, - {"3","2.1"}, - {"4","21.1"}, - {"5","4.1"}, - {"6","3.2"}, - {"7","4.2"}, - {"8","rsc"}, - {"9","2.3"}, - {"10","2.4"}, - {"11","1.4"}, - {"12","5.5"}, - {"12","5.6"}, - {"12","5.7"}, - {"13","6.3"}, - {"14","6.1"}, - {"14","6.2"}, - {"15","1.5"}, - {"16","12.12"}, - {"17","5.3"}, - {"18","rsc"}, - {"19","7.1"}, - {"20","rsc"}, - {"21","5.2"}, - {"22","8.7"}, - {"23","8.10"}, - {"24","8.11"}, - {"25","8.9"}, - {"26","8.4"}, - {"27","8.8"}, - {"28","rsc"}, - {"29","5.4"}, - {"30","9.1"}, - {"31","9.2"}, - {"32","9.3"}, - {"33","12.4"}, - {"34","12.5"}, - {"35","13.1"}, - {"36","12.6"}, - {"37","10.5"}, - {"37","12.7"}, - {"38","12.8"}, - {"39","12.9"}, - {"40","12.3"}, - {"41","3.3"}, - {"42","12.10"}, - {"43","10.1"}, - {"44","rsc"}, - {"45","11.1"}, - {"45","11.2"}, - {"45","11.3"}, - {"45","11.4"}, - {"45","11.5"}, - {"46","12.2"}, - {"47","12.1"}, - {"48","10.4"}, - {"49","13.2"}, - {"50","13.3"}, - {"51","12.11"}, - {"52","14.1"}, - {"53","14.2"}, - {"54","14.3"}, - {"55","rsc"}, - {"56","14.4"}, - {"57","14.5"}, - {"58","rsc"}, - {"59","14.8"}, - {"59","14.9"}, - {"60","14.10"}, - {"61","15.1"}, - {"61","15.2"}, - {"62","15.3"}, - {"63","15.4"}, - {"64","15.5"}, - {"65","13.4"}, - {"66","13.5"}, - {"67","13.6"}, - {"68","8.6"}, - {"69","16.1"}, - {"70","16.2"}, - {"71","8.1"}, - {"72","8.3"}, - {"73","16.3"}, - {"74","16.4"}, - {"75","8.2"}, - {"76","16.5"}, - {"77","10.2"}, - {"78","16.6"}, - {"79","rsc"}, - {"80","rsc"}, - {"81","16.7"}, - {"82","14.7"}, - {"83","16.8"}, - {"84","rsc"}, - {"85","16.9"}, - {"86","16.10"}, - {"87","8.5"}, - {"87","19.1"}, - {"88","19.2"}, - {"89","19.3"}, - {"90","19.4"}, - {"91","19.5"}, - {"92","19.6"}, - {"93","19.7"}, - {"94","19.8"}, - {"95","19.9"}, - {"96","19.10"}, - {"97","19.11"}, - {"98","19.12"}, - {"98","19.13"}, - {"99","3.4"}, - {"100","19.14"}, - {"101","17.1"}, - {"101","17.2"}, - {"101","17.4"}, - {"102","17.5"}, - {"103","17.3"}, - {"104","rsc"}, - {"105","rsc"}, - {"106","17.6"}, - {"107","rsc"}, - {"108","18.1"}, - {"109","18.2"}, - {"109","18.3"}, - {"110","18.4"}, - {"111","6.4"}, - {"112","6.5"}, - {"113","rsc"}, - {"114","20.1"}, - {"115","20.2"}, - {"116","3.6"}, - {"117","20.3"}, - {"118","20.4"}, - {"119","20.5"}, - {"120","20.6"}, - {"121","rsc"}, - {"122","20.7"}, - {"123","20.8"}, - {"124","20.9"}, - {"125","20.10"}, - {"126","20.11"}, - {"127","20.12"} -}; - -std::pair Mutator0RuleChecks; - -std::multimap MC3EquivalencyMap; - -std::unordered_map SaferCPPEquivalencyMap; -/**********************************************************************************************************************/ -class MutatorLVL0Tests -{ - public: - MutatorLVL0Tests() {} - - void run(void) - { - - } - - private: - -}; -/**********************************************************************************************************************/ -class mutagenAncestryReport// : public Devi::XMLReportBase -{ - public: - mutagenAncestryReport(std::vector> __dss, std::vector __wps) : DoomedStrains(__dss), WeakPoints(__wps) - { - RootPointer = Doc.NewElement("mutagen:Report"); - RootPointer->SetAttribute("xmlns:mutagen", "http://www.w3.org/2001/XMLSchema"); - } - - ~mutagenAncestryReport() - { - Doc.InsertEndChild(RootPointer); - } - - virtual void AddNode(void) - { - XMLElement* MGene = Doc.NewElement("DoomedStrains"); - - for (auto &iter : DoomedStrains) - { - XMLElement* NodeDoomedStrain = Doc.NewElement("DoomedStrain"); - - for (auto &iterer : iter) - { - XMLElement* Child = Doc.NewElement("Strain"); - Child->SetText(iterer.c_str()); - NodeDoomedStrain->InsertEndChild(Child); - } - - MGene->InsertEndChild(NodeDoomedStrain); - } - - RootPointer->InsertEndChild(MGene); - } - - void AddNodeWeakPoint(void) - { - XMLElement* WeakStrain = Doc.NewElement("WeakStrains"); - - for (auto &iter : WeakPoints) - { - XMLElement* Child = Doc.NewElement("WeakStrain"); - Child->SetAttribute("WeakStrainType", iter.PlaceHolderStringForType.c_str()); - Child->SetAttribute("File", iter.File.c_str()); - Child->SetAttribute("LineNumber", iter.LineNumber); - Child->SetAttribute("ColumnNumber", iter.ColumnNumber); - WeakStrain->InsertEndChild(Child); - } - - RootPointer->InsertEndChild(WeakStrain); - } - -#if 1 - void CreateReport() - { - Doc.InsertFirstChild(RootPointer); - } - - void SaveReport(const char* __filename) - { - Doc.InsertEndChild(RootPointer); - - XMLError XMLErrorResult = Doc.SaveFile(__filename); - - if (XMLErrorResult != XML_SUCCESS) - { - std::cerr << "could not write xml misra report.\n"; - } - } -#endif - - private: - std::vector> DoomedStrains; - std::vector WeakPoints; -#if 1 - XMLElement* RootPointer; - XMLDocument Doc; -#endif -}; -/**********************************************************************************************************************/ -#define EXTRACT_MUTAGEN - -class MutagenExtraction -{ - public: - MutagenExtraction() {} - - ~MutagenExtraction() {} - - void ExtractAncestry(clang::ast_type_traits::DynTypedNode __dtn, clang::ASTContext &__astx) - { - clang::ASTContext::DynTypedNodeList DNL = __astx.getParents(__dtn); - if (DNL.empty()) return void(); - - /*FIXME-a LastStrain. obviously well end up losing some parents in cpp if we're just picking up the - * first parent from the list.*/ - LastStrain.push_back(DNL[0].getNodeKind().asStringRef().str()); - clang::ast_type_traits::DynTypedNode DTN = DNL[0]; - - /*FIXME-what does getparents return when there are no more parents to return?*/ - while (DTN.getNodeKind().asStringRef().str() != "FunctionDecl") - { - DNL = __astx.getParents(DTN); - if (DNL.empty()) return void(); - DTN = DNL[0]; - LastStrain.push_back(DTN.getNodeKind().asStringRef().str()); - } - - MutantStrainsAncestry.push_back(LastStrain); - LastStrain.clear(); - } - - void ExtractWeakPoints(SourceLocation __sl, SourceManager &__sm, std::string __type) - { - WeakPoint tmp = WeakPoint(__type, __sm.getFilename(__sl).str(), \ - __sm.getSpellingLineNumber(__sl), __sm.getSpellingColumnNumber(__sl)); - WeakPoints.push_back(tmp); - } - - void ExtractWeakPoints(FullSourceLoc __fsl, SourceLocation __sl, std::string __type) - { - WeakPoint tmp = WeakPoint(__type, __fsl.getManager().getFilename(__sl).str(), \ - __fsl.getSpellingLineNumber(), __fsl.getSpellingColumnNumber()); - WeakPoints.push_back(tmp); - } - - void ExtractWeakPoints(std::string __type, unsigned int __ln, unsigned int __cn, std::string __file) - { - WeakPoint tmp = WeakPoint(__type, __file, __ln, __cn); - WeakPoints.push_back(tmp); - } - - void DumpLast(void) - { - for (auto &iter : LastStrain) - { - std::cout << "DoomedStrain : " << iter << "\n"; - } - } - - void DumpAll(void) - { - for (auto &iter : MutantStrainsAncestry) - { - for (auto &iterer : iter) - { - std::cout << "DoomedStrainAll : " << iterer << "\n"; - } - - std::cout << "\n"; - } - } - - void XMLReportAncestry(void) - { - mutagenAncestryReport MAR(MutantStrainsAncestry, WeakPoints); - MAR.CreateReport(); - MAR.AddNode(); - MAR.AddNodeWeakPoint(); - MAR.SaveReport("m0.xml"); - } - - private: - std::vector LastStrain; - std::vector> MutantStrainsAncestry; - std::vector WeakPoints; -}; -/**********************************************************************************************************************/ -#endif -/**********************************************************************************************************************/ -/*last line intentionally left blank*/ - diff --git a/mutator-lvl1.cpp b/mutator-lvl1.cpp deleted file mode 100644 index c6082f9..0000000 --- a/mutator-lvl1.cpp +++ /dev/null @@ -1,622 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ -/**********************************************************************************************************************/ -/*FIXME-all classes should use replacements.*/ -/**********************************************************************************************************************/ -/*included modules*/ -/*project headers*/ -#include "mutator_aux.h" -/*standard headers*/ -#include -#include -#include -/*LLVM headers*/ -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/IR/Function.h" -/**********************************************************************************************************************/ -/*used namespaces*/ -using namespace llvm; -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::driver; -using namespace clang::tooling; -/**********************************************************************************************************************/ -/*global vars*/ -/*the variable that holds the previously-matched SOC for class StmtTrap.*/ -std::string g_linenoold; - -static llvm::cl::OptionCategory MutatorLVL1Cat("mutator-lvl1 options category"); -/**********************************************************************************************************************/ -/*matcher callback for something.*/ -class FunctionHandler : public MatchFinder::MatchCallback { -public: - FunctionHandler (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("binopeq") != nullptr) - { - /*get the matched node.*/ - const BinaryOperator *BinOp = MR.Nodes.getNodeAs("binopeq"); - - /*get the sourceloation.*/ - SourceLocation BinOpSL = BinOp->getLocStart(); - - BinOpSL = Devi::SourceLocationHasMacro(BinOpSL, Rewrite, "start"); - /*does the sourcelocation include a macro expansion?*/ - - /*replace it.*/ -#if 0 - Rewrite.ReplaceText(BinOpSL, 2U , "XXX"); -#endif - } - else - { - std::cout << "the macther -binopeq- returned nullptr!" << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class StmtTrapIf : public MatchFinder::MatchCallback { -public: - StmtTrapIf (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run (const MatchFinder::MatchResult &MR) - { - /*just in case*/ - if (MR.Nodes.getNodeAs("iftrap") != nullptr) - { - /*getting the matched ifStmt.*/ - const IfStmt *TrapIf = MR.Nodes.getNodeAs("iftrap"); - - /*getting the condition of the matched ifStmt.*/ - const Expr *IfCond = TrapIf->getCond(); - - /*getting the sourcerange of the condition of the trapped ifstmt.*/ - SourceLocation TrapIfCondSL = IfCond->getLocStart(); - TrapIfCondSL = Devi::SourceLocationHasMacro(TrapIfCondSL, Rewrite, "start"); - SourceLocation TrapIfCondSLEnd = IfCond->getLocEnd(); - TrapIfCondSLEnd = Devi::SourceLocationHasMacro(TrapIfCondSLEnd, Rewrite, "end"); - SourceRange TrapIfCondSR; - TrapIfCondSR.setBegin(TrapIfCondSL); - TrapIfCondSR.setEnd(TrapIfCondSLEnd); - - /*replacing the condition with the utility trap function.*/ -#if 0 - Rewrite.ReplaceText(TrapIfCondSR, "C_Trap_P()"); -#endif - } - else - { - std::cout << "the matcher -iftrap- returned nullptr!" << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class StmtTrap : public MatchFinder::MatchCallback { -public: - StmtTrap (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - /*if there are more than 2 statements in the traditional sense in one line, the behavior is undefined.*/ - /*for now this class only finds an SOC. later to be used for something useful.*/ - virtual void run (const MatchFinder::MatchResult &MR) - { - /*out of paranoia*/ - if (MR.Nodes.getNodeAs("stmttrap") != nullptr) - { - const Stmt *StmtTrapMR = MR.Nodes.getNodeAs("stmttrap"); - - SourceLocation STSL = StmtTrapMR->getLocStart(); - STSL = Devi::SourceLocationHasMacro(STSL, Rewrite, "start"); - SourceLocation STSLE = StmtTrapMR->getLocEnd(); - STSLE = Devi::SourceLocationHasMacro(STSLE, Rewrite, "end"); - - /*just getting the SOC of the matched statement out of its sourcelocation.*/ - /*this only works since we are guaranteed the same and known matching pattern by MatchFinder.*/ - size_t startloc = 0U; - size_t endloc = 0U; - std::string lineno; - startloc = STSL.printToString(*MR.SourceManager).find(":", 0U); - endloc = STSLE.printToString(*MR.SourceManager).find(":", startloc + 1U); - lineno = STSL.printToString(*MR.SourceManager).substr(startloc, endloc - startloc); - - /*just prints out the sourcelocations for diagnostics.*/ -#if 0 - std::cout << STSL.printToString(*MR.SourceManager) << std::endl; - std::cout << STSLE.printToString(*MR.SourceManager) << std::endl; - std::cout << startloc << "---" << endloc << "---" << lineno << std::endl; -#endif - - /*have we matched a new SOC? if yes:*/ - if (lineno != g_linenoold) - { - SourceRange SR; - SR.setBegin(StmtTrapMR->getLocStart()); - SR.setEnd(StmtTrapMR->getLocEnd()); - -#if 0 - Rewrite.InsertText(StmtTrapMR->getLocStart(), "XXX", "true", "true"); -#endif - } - else - { - /*intentionally left blank.*/ - } - - /*set the string representing the old SOC line number to the one matched now.*/ - g_linenoold = lineno; - } - else - { - std::cout << "the matcher -stmttrap- returned nullptr!" << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class StmtRet : public MatchFinder::MatchCallback -{ -public: - StmtRet (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run (const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("stmtret") != nullptr) - { - /*getting the returnstmt.*/ - const ReturnStmt *RetStmtMR = MR.Nodes.getNodeAs("stmtret"); - - /*getting the sourcerange of the matched returnstmt.*/ - SourceLocation RSMR = RetStmtMR->getLocStart(); - RSMR = Devi::SourceLocationHasMacro(RSMR, Rewrite, "start"); - SourceLocation RSMRE = RetStmtMR->getLocEnd(); - RSMRE = Devi::SourceLocationHasMacro(RSMRE, Rewrite, "end"); - SourceRange RSMRSR; - RSMRSR.setBegin(RSMR); - RSMRSR.setEnd(RSMRE); - -#if 0 - Rewrite.ReplaceText(RSMRSR, "C_Trap_P()"); -#endif - } - else - { - std::cout << "matcher -stmtret- returned nullptr." << std::endl; - } - } - -private: - Rewriter &Rewrite; - -}; -/**********************************************************************************************************************/ -class ForFixer : public MatchFinder::MatchCallback -{ -public: - ForFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - /*adds curly braces for forstmts that don't have it.*/ - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mrfor") != nullptr) - { - const ForStmt *MRFor = MR.Nodes.getNodeAs("mrfor"); - - Rewriter::RewriteOptions opts; - - SourceLocation MRForSL = MRFor->getBody()->getLocStart(); - MRForSL = Devi::SourceLocationHasMacro(MRForSL, Rewrite, "start"); - SourceLocation MRForSLE = MRFor->getBody()->getLocEnd(); - MRForSLE = Devi::SourceLocationHasMacro(MRForSLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(MRForSL); - SR.setEnd(MRForSLE); - - int RangeSize = Rewrite.getRangeSize(SR, opts); - - Rewrite.InsertText(MRForSL, "{\n", true, false); - /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ - /*line-terminating semicolons are not included in the matches.*/ - Rewrite.InsertTextAfterToken(MRForSL.getLocWithOffset(RangeSize), "\n}"); - } - else - { - std::cout << "matcher -mrfor- returned nullptr." << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class WhileFixer : public MatchFinder::MatchCallback -{ -public: - WhileFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - /*adds curly braces for whilestmts that don't have it.*/ - virtual void run (const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mrwhile") != nullptr) - { - const WhileStmt *MRWhile = MR.Nodes.getNodeAs("mrwhile"); - -#if 0 - std::cout << MRWhile->getBody()->getLocStart().printToString(*MR.SourceManager) << std::endl; - std::cout << MRWhile->getBody()->getLocEnd().printToString(*MR.SourceManager) << std::endl; -#endif - - SourceLocation WFSL = MRWhile->getBody()->getLocStart(); - WFSL = Devi::SourceLocationHasMacro(WFSL, Rewrite, "start"); - SourceLocation WFSLE = MRWhile->getBody()->getLocEnd(); - WFSLE = Devi::SourceLocationHasMacro(WFSLE, Rewrite, "end"); - - /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ - /*line-terminating semicolons are not included in the matches.*/ - Rewrite.InsertText(WFSL, "{\n", true, true); - Rewrite.InsertTextAfterToken(WFSLE.getLocWithOffset(2U), "\n}"); - } - else - { -#if 1 - std::cout << "matcher -mrwhile- returned nullptr." << std::endl; -#endif - } - } - - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class IfElseFixer : public MatchFinder::MatchCallback -{ -public: - IfElseFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - /*underdev*/ - if (MR.Nodes.getNodeAs("mrifelse") != nullptr) - { - const IfStmt *ElseIf = MR.Nodes.getNodeAs("mrifelse"); - //const IfStmt *LastIf = MR.Nodes.getNodeAs("mrifelse"); - - SourceLocation IFESL = ElseIf->getElse()->getLocStart(); - IFESL = Devi::SourceLocationHasMacro(IFESL, Rewrite, "start"); - SourceLocation IFESLE = ElseIf->getElse()->getLocEnd(); - IFESLE = Devi::SourceLocationHasMacro(IFESLE, Rewrite, "end"); - SourceRange SR; - SR.setBegin(IFESL); - SR.setEnd(IFESLE); - - clang::Rewriter::RewriteOptions opts; - - int RangeSize = Rewrite.getRangeSize(SR, opts); - - //std::cout << IFESLE.printToString(*MR.SourceManager) << "\n" << std::endl; - -#if 1 - Rewrite.InsertText(IFESL, "{\n", true, true); - Rewrite.InsertTextAfterToken(IFESL.getLocWithOffset(RangeSize), "\n}"); -#endif - } - else - { - std::cout << "matcher -mrifelse- returned nullptr." << std::endl; - } - } - - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class IfFixer : public MatchFinder::MatchCallback -{ -public: - IfFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - /*adds curly braces to ifstmts that dont have it.*/ - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mrif") != nullptr) - { - const IfStmt *MRIf = MR.Nodes.getNodeAs("mrif"); - - SourceLocation FFSL = MRIf->getThen()->getLocStart(); - FFSL = Devi::SourceLocationHasMacro(FFSL, Rewrite, "start"); - SourceLocation FFSLE = MRIf->getThen()->getLocEnd(); - FFSLE = Devi::SourceLocationHasMacro(FFSLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(FFSL); - SR.setEnd(FFSLE); - Rewriter::RewriteOptions opts; - int RangeSize = Rewrite.getRangeSize(SR, opts); - - /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/ - /*line-terminating semicolons are not included in the matches.*/ -#if 1 - Rewrite.InsertText(FFSL, "{\n", true, true); - Rewrite.InsertTextAfterToken(FFSL.getLocWithOffset(RangeSize), "\n}"); -#endif - } - else - { - std::cout << "matcher -mrif- returned nullptr." << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class SwitchFixer : public MatchFinder::MatchCallback -{ -public: - SwitchFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("bubba-hotep") != nullptr) - { - const CaseStmt *CS = MR.Nodes.getNodeAs("bubba-hotep"); - - const Stmt *SB = CS->getSubStmt(); - - SourceLocation SBSL = SB->getLocStart(); - SBSL = Devi::SourceLocationHasMacro(SBSL, Rewrite, "start"); - SourceLocation SBSLE = SB->getLocEnd(); - SBSLE = Devi::SourceLocationHasMacro(SBSLE, Rewrite, "end"); - - SourceLocation SL = CS->getLocStart(); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SourceLocation SLE = CS->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - Rewriter::RewriteOptions opts; - int RangeSize [[maybe_unused]] = Rewrite.getRangeSize(SR, opts); - -#if 1 - Rewrite.InsertText(SBSL, "{\n", true, true); - Rewrite.InsertTextAfterToken(SL.getLocWithOffset(RangeSize), "\n}"); -#endif - } - else - { - std::cout << "matcher -bubba-hotep- returned nullptr." << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class SwitchDfFixer : public MatchFinder::MatchCallback -{ -public: - SwitchDfFixer (Rewriter &Rewrite) : Rewrite (Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("mumma-hotep") != nullptr) - { - const DefaultStmt *DS = MR.Nodes.getNodeAs("mumma-hotep"); - - const Stmt *SB = DS->getSubStmt(); - - SourceLocation CSL = SB->getLocStart(); - CSL = Devi::SourceLocationHasMacro(CSL, Rewrite, "start"); - - SourceLocation SL = DS->getLocStart(); - SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); - SourceLocation SLE = DS->getLocEnd(); - SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end"); - - SourceRange SR; - SR.setBegin(SL); - SR.setEnd(SLE); - Rewriter::RewriteOptions opts; - int RangeSize [[maybe_unused]] = Rewrite.getRangeSize(SR, opts); - -#if 1 - Rewrite.InsertText(CSL, "{\n", true, true); - Rewrite.InsertTextAfterToken(SL.getLocWithOffset(RangeSize), "\n}"); -#endif - } - else - { - std::cout << "matcher -mumma-hotep- returned nullptr." << std::endl; - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class IfConstSwapper : public MatchFinder::MatchCallback -{ -public: - IfConstSwapper (Rewriter &Rewrite) : Rewrite(Rewrite) {} - - virtual void run(const MatchFinder::MatchResult &MR) - { - if (MR.Nodes.getNodeAs("ifconstswapbinop") != nullptr) - { - const BinaryOperator* BO = MR.Nodes.getNodeAs("ifconstswapbinop"); - - const Expr* LHS = BO->getLHS(); - const Expr* RHS = BO->getRHS(); - - ASTContext *const ASTC = MR.Context; - SourceManager *const SM = MR.SourceManager; - - if (RHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects) && !LHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects)) - { - SourceLocation SLLHS = LHS->getLocStart(); - SLLHS = Devi::SourceLocationHasMacro(SLLHS, Rewrite, "start"); - SourceLocation SLELHS = LHS->getLocStart(); - SLELHS = Devi::SourceLocationHasMacro(SLELHS, Rewrite, "end"); - SourceRange SRLHS; - SRLHS.setBegin(SLLHS); - SRLHS.setEnd(SLELHS); - - if (!SM->isInMainFile(SLLHS)) - { - return void(); - } - - if (SM->isInSystemHeader(SLLHS)) - { - return void(); - } - - SourceLocation SLRHS = RHS->getLocStart(); - SLRHS = Devi::SourceLocationHasMacro(SLRHS, Rewrite, "start"); - SourceLocation SLERHS = RHS->getLocEnd(); - SLERHS = Devi::SourceLocationHasMacro(SLERHS, Rewrite, "end"); - SourceRange SRRHS; - SRRHS.setBegin(SLRHS); - SRRHS.setEnd(SLERHS); - - const std::string LHSString = Rewrite.getRewrittenText(SRLHS); - const std::string RHSString = Rewrite.getRewrittenText(SRRHS); - -#if 0 - std::cout << "lhs:" << LHSString << " " << "rhs:" << RHSString << " " << SLLHS.printToString(*SM) << std::endl; -#endif - - StringRef LHSRef = StringRef(LHSString); - StringRef RHSRef = StringRef(RHSString); - - Rewriter::RewriteOptions opts; - int RangeSizeLHS = Rewrite.getRangeSize(SRLHS, opts); - int RangeSizeRHS = Rewrite.getRangeSize(SRRHS, opts); - - Rewrite.ReplaceText(SRLHS.getBegin(), RangeSizeLHS, RHSRef); - Rewrite.ReplaceText(SRRHS.getBegin(), RangeSizeRHS, LHSRef); - } - } - } - -private: - Rewriter &Rewrite; -}; -/**********************************************************************************************************************/ -class MyASTConsumer : public ASTConsumer { - -public: - MyASTConsumer(Rewriter &R) : HandlerForFunction(R), HandlerForIfTrap(R), HandlerForStmtTrap(R), HandlerForStmtRet(R), HandlerForFixer(R), \ - HandlerForWhile(R), HandlerForIfElse(R), HandlerForIfFixer(R), HandlerForSwitchFixer(R), HandlerForSwitchDf(R), HandlerForIfConstSwap(R) - { - Matcher.addMatcher(binaryOperator(hasOperatorName("==")).bind("binopeq"), &HandlerForFunction); - - Matcher.addMatcher(ifStmt(hasCondition(anything())).bind("iftrap"), &HandlerForIfTrap); - - Matcher.addMatcher(stmt().bind("stmttrap") , &HandlerForStmtTrap); - - Matcher.addMatcher(returnStmt().bind("stmtret"), &HandlerForStmtRet); - - Matcher.addMatcher(forStmt(unless(hasDescendant(compoundStmt()))).bind("mrfor"), &HandlerForFixer); - - Matcher.addMatcher(whileStmt(unless(hasDescendant(compoundStmt()))).bind("mrwhile"), &HandlerForWhile); - - Matcher.addMatcher(ifStmt(allOf(hasElse(unless(ifStmt())), hasElse(unless(compoundStmt())))).bind("mrifelse"), &HandlerForIfElse); - - Matcher.addMatcher(ifStmt(unless(hasDescendant(compoundStmt()))).bind("mrif"), &HandlerForIfFixer); - - Matcher.addMatcher(switchStmt(forEachDescendant(caseStmt(unless(hasDescendant(compoundStmt()))).bind("bubba-hotep"))), &HandlerForSwitchFixer); - - Matcher.addMatcher(switchStmt(hasDescendant(defaultStmt(unless(hasDescendant(compoundStmt()))).bind("mumma-hotep"))), &HandlerForSwitchDf); - - Matcher.addMatcher(ifStmt(has(binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("="))).bind("ifconstswapbinop"))).bind("ifconstswapper"), &HandlerForIfConstSwap); - } - - void HandleTranslationUnit(ASTContext & Context) override { - Matcher.matchAST(Context); - } - -private: - FunctionHandler HandlerForFunction; - StmtTrapIf HandlerForIfTrap; - StmtTrap HandlerForStmtTrap; - StmtRet HandlerForStmtRet; - ForFixer HandlerForFixer; - WhileFixer HandlerForWhile; - IfElseFixer HandlerForIfElse; - IfFixer HandlerForIfFixer; - SwitchFixer HandlerForSwitchFixer; - SwitchDfFixer HandlerForSwitchDf; - IfConstSwapper HandlerForIfConstSwap; - MatchFinder Matcher; -}; -/**********************************************************************************************************************/ -class MyFrontendAction : public ASTFrontendAction -{ -public: - MyFrontendAction() {} - void EndSourceFileAction() override - { - TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); - } - - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override - { - TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); - return llvm::make_unique(TheRewriter); - } - -private: - Rewriter TheRewriter; -}; -/**********************************************************************************************************************/ -/*Main*/ -int main(int argc, const char **argv) -{ - CommonOptionsParser op(argc, argv, MutatorLVL1Cat); - ClangTool Tool(op.getCompilations(), op.getSourcePathList()); - - return Tool.run(newFrontendActionFactory().get()); -} -/*last line intentionally left blank.*/ diff --git a/mutator-lvl2.cpp b/mutator-lvl2.cpp deleted file mode 100644 index c585734..0000000 --- a/mutator-lvl2.cpp +++ /dev/null @@ -1,120 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ -/**********************************************************************************************************************/ -/*FIXME-all classes should use replacements.*/ -/**********************************************************************************************************************/ -/*included modules*/ -/*project headers*/ -//#include "mutator_aux.h" -/*standard headers*/ -#include -#include -#include -/*LLVM headers*/ -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/LLVM.h" -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/CodeGen/BackendUtil.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Function.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Linker/Linker.h" -/**********************************************************************************************************************/ -/*used namespaces*/ -using namespace llvm; -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::driver; -using namespace clang::tooling; -/**********************************************************************************************************************/ -/*global vars*/ -static llvm::cl::OptionCategory MatcherSampleCategory("Matcher Sample"); -/**********************************************************************************************************************/ -class BlankDiagConsumer : public clang::DiagnosticConsumer -{ - public: - BlankDiagConsumer() = default; - virtual ~BlankDiagConsumer() {} - virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override {} -}; -/**********************************************************************************************************************/ -class MyASTConsumer : public ASTConsumer { -public: - MyASTConsumer(Rewriter &R) { - } - - void HandleTranslationUnit(ASTContext &Context) { - std::cout << "i was here\n"; - //Matcher.matchAST(Context); - } - -private: - MatchFinder Matcher; -}; -/**********************************************************************************************************************/ -class MyFrontendAction : public ASTFrontendAction { -public: - MyFrontendAction() {} - void EndSourceFileAction() override { - //TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); - } - - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override { - DiagnosticsEngine &DE = CI.getPreprocessor().getDiagnostics(); - DE.setClient(BDCProto, false); - TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); - //return llvm::make_unique(new MyASTConsumer(TheRewriter)); - //return llvm::make_unique(*new MyASTConsumer(TheRewriter)); - return llvm::make_unique(TheRewriter); - //return std::unique_ptr(new ASTConsumer); - } - -private: - BlankDiagConsumer* BDCProto = new BlankDiagConsumer; - Rewriter TheRewriter; -}; -/**********************************************************************************************************************/ -/*Main*/ -int main(int argc, const char **argv) { - CommonOptionsParser op(argc, argv, MatcherSampleCategory); - ClangTool Tool(op.getCompilations(), op.getSourcePathList()); - - int ret; - ret = Tool.run(newFrontendActionFactory().get()); - std::cout << "fucking done!\n"; - return ret; -} -/*last line intentionally left blank.*/ - diff --git a/mutator_aux.cpp b/mutator_aux.cpp deleted file mode 100644 index a382764..0000000 --- a/mutator_aux.cpp +++ /dev/null @@ -1,152 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*********************************************************************************************************************/ -/*inclusion directives*/ -#include "mutator_aux.h" -#include -#include -#include -#include -#include "clang/AST/AST.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "tinyxml2/tinyxml2.h" -#include "json/json.hpp" -/*********************************************************************************************************************/ -using namespace clang; -/*********************************************************************************************************************/ -namespace Devi { -/*a simple function that checks the sourcelocations for a macro expansion. returns the sourcelocation without -macro expansion address.*/ -#if 1 -SourceLocation SourceLocationHasMacro [[deprecated("doesnt work")]] (SourceLocation SL, Rewriter &Rewrite, std::string Kind) { - /*does the sourcelocation include a macro expansion?*/ - if ( SL.isMacroID()) { - /*get the expansion range which is startloc and endloc*/ - std::pair expansionRange = Rewrite.getSourceMgr().getImmediateExpansionRange(SL); - if (Kind == "start") { - return (expansionRange.first); - } else if (Kind == "end") { - return (expansionRange.second); - } else { - std::cout << "the third argument of Devi::SourceLocationHasMacro is invalid." << std::endl; - } - } else { - return (SL); - } - return (SL); -} -#endif - -SourceLocation SourceLocationHasMacro(SourceLocation __sl, Rewriter &__rewrite) -{ - if (__sl.isMacroID()) { - return __rewrite.getSourceMgr().getSpellingLoc(__sl); - } else { - return __sl; - } -} - -SourceLocation getSLSpellingLoc(SourceLocation __sl, Rewriter &__rewrite) { - if (__sl.isMacroID()) {return __rewrite.getSourceMgr().getSpellingLoc(__sl);} - else {return __sl;} -} -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -/*the first argument is the option SysHeader from the mutator-lvl0 cl.*/ -bool IsTheMatchInSysHeader(bool SysHeaderFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) { - ASTContext *const ASTC = MR.Context; - const SourceManager &SM = ASTC->getSourceManager(); - - if (SM.isInSystemHeader(SL) && !SysHeaderFlag) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, const SourceManager &SM, SourceLocation SL) { - if (SM.isInSystemHeader(SL) && !SysHeaderFlag) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader, SourceLocation SL) { - if (SysHeader && !SysHeaderFlag) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader) -{ - if (SysHeader && !SysHeaderFlag) { - return true; - } else { - return false; - } -} -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -bool IsTheMatchInMainFile(bool MainFileFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL) { - ASTContext *const ASTC = MR.Context; - const SourceManager &SM = ASTC->getSourceManager(); - if (SM.isInMainFile(SL) || (!SM.isInMainFile(SL) && !MainFileFlag)) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInMainFile(bool MainFileFlag, const SourceManager &SM, SourceLocation SL) { - if (SM.isInMainFile(SL) || (!SM.isInMainFile(SL) && !MainFileFlag)) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile, SourceLocation SL) { - if (MainFile || (!MainFile && !MainFileFlag)) { - return true; - } else { - return false; - } -} - -bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile) { - if (MainFile || (!MainFile && !MainFileFlag)) { - return true; - } else { - return false; - } -} -/*********************************************************************************************************************/ -/*End of namespace Devi*/ -} -/*********************************************************************************************************************/ -/*last line intentionally left blank.*/ - diff --git a/mutator_aux.h b/mutator_aux.h deleted file mode 100644 index 3670df8..0000000 --- a/mutator_aux.h +++ /dev/null @@ -1,76 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*********************************************************************************************************************/ -/*first line intentionally left blank*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*********************************************************************************************************************/ -/*inclusion guard*/ -#ifndef MUTATOR_AUX_H -#define MUTATOR_AUX_H -/*********************************************************************************************************************/ -/*inclusion directives*/ -#include -#include -#include "clang/AST/AST.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Rewrite/Core/Rewriter.h" -/*********************************************************************************************************************/ -/*Macros and definitions*/ -#define CheckSLValidity(SL) \ - do {\ - if (!SL.isValid()) {return void();}}\ - while(0); -/*********************************************************************************************************************/ -using namespace clang; -/*********************************************************************************************************************/ -namespace Devi { -enum class NodeKind {NoValue, VarDecl, FieldDecl, RecordDecl, LabelDecl, FunctionDecl, TypedefDecl, ParmVarDecl, EnumDecl, EnumConstDecl}; - -enum class Scope {NoValue, TU, Block}; - -enum class FunctionDeclKind {NoValue, Definition, Declaration}; -/*********************************************************************************************************************/ -SourceLocation SourceLocationHasMacro(SourceLocation SL, Rewriter &Rewrite, std::string Kind); - -SourceLocation SourceLocationHasMacro(SourceLocation __sl, Rewriter &__rewrite); - -SourceLocation getSLSpellingLoc(SourceLocation __sl, Rewriter &__rewrite); -/*********************************************************************************************************************/ -bool IsTheMatchInSysHeader(bool SysHeaderFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL); - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, const SourceManager &SM, SourceLocation SL); - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader, SourceLocation SL); - -bool IsTheMatchInSysHeader(bool SysHeaderFlag, bool SysHeader); -/*********************************************************************************************************************/ -bool IsTheMatchInMainFile(bool MainFileFlag, const ast_matchers::MatchFinder::MatchResult &MR, SourceLocation SL); - -bool IsTheMatchInMainFile(bool MainFileFlag, const SourceManager &SM, SourceLocation SL); - -bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile, SourceLocation SL); - -bool IsTheMatchInMainFile(bool MainFileFlag, bool MainFile); -/*********************************************************************************************************************/ -/*end of namespace Devi*/ -} -#endif -/*********************************************************************************************************************/ -/*last line intentionally left blank.*/ - diff --git a/mutator_report.cpp b/mutator_report.cpp deleted file mode 100644 index 51fd342..0000000 --- a/mutator_report.cpp +++ /dev/null @@ -1,314 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*first line intentionally left blank.*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*********************************************************************************************************************/ -/*inclusion directives*/ -#include "mutator_report.h" -#include -#include -#include -#include -#include "clang/AST/AST.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "tinyxml2/tinyxml2.h" -#include "json/json.hpp" -/*********************************************************************************************************************/ -using namespace clang; -using namespace tinyxml2; -using json = nlohmann::json; -/*********************************************************************************************************************/ -namespace Devi { -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -/****************************************************XMLReportBase****************************************************/ - XMLReportBase::XMLReportBase() - { - RootPointer = Doc.NewElement("mutagen:Report"); - RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema"); - } - - XMLReportBase::~XMLReportBase() - { - Doc.InsertEndChild(RootPointer); - } - - void XMLReportBase::CreateReport() - { - Doc.InsertFirstChild(RootPointer); - } - - void XMLReportBase::SaveReport(const char* __filename) - { - Doc.InsertEndChild(RootPointer); - - XMLError XMLErrorResult = Doc.SaveFile(__filename); - - if (XMLErrorResult != XML_SUCCESS) - { - std::cerr << "could not write xml misra report(base).\n"; - } - } -/************************************************end of XMLReportBase*************************************************/ -/*********************************************************************************************************************/ -/******************************************************XMLReport******************************************************/ -XMLReport::XMLReport() -{ - RootPointer = XMLReportDoc.NewElement("mutator:Report"); - RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema"); -} - -XMLReport::~XMLReport() -{ - XMLReportDoc.InsertEndChild(RootPointer); -} - -void XMLReport::XMLCreateReport() -{ - XMLReportDoc.InsertFirstChild(RootPointer); -} - -/*it is the caller's responsibility to make sure the sourcelocation passed to this overload of the member function -contains only the spelling location.*/ -void XMLReport::XMLAddNode(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(1) of XMLAddNode is not valid."); - - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - unsigned LineNumber = FSL.getSpellingLineNumber(); - unsigned ColumnNumber = FSL.getSpellingColumnNumber(); - - const SourceManager& SM = FSL.getManager(); - std::string FileNameString = SM.getFilename(SL).str(); - - XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); - MisraElement->SetText(Description.c_str()); - MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); - MisraElement->SetAttribute("FileName", FileNameString.c_str()); - MisraElement->SetAttribute("SpellingLineNumber", LineNumber); - MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); - RootPointer->InsertEndChild(MisraElement); -} - -void XMLReport::XMLAddNode(FullSourceLoc FullSrcLoc, SourceLocation SL, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(2) of XMLAddNode is not valid."); - - unsigned LineNumber = FullSrcLoc.getSpellingLineNumber(); - unsigned ColumnNumber = FullSrcLoc.getSpellingColumnNumber(); - - const SourceManager& SM = FullSrcLoc.getManager(); - std::string FileNameString = SM.getFilename(SL).str(); - - XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); - MisraElement->SetText(Description.c_str()); - MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); - MisraElement->SetAttribute("FileName", FileNameString.c_str()); - MisraElement->SetAttribute("SpellingLineNumber", LineNumber); - MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); - RootPointer->InsertEndChild(MisraElement); -} - -void XMLReport::XMLAddNode(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description) -{ - SL = SM.getSpellingLoc(SL); - - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - unsigned LineNumber = SM.getSpellingLineNumber(SL); - unsigned ColumnNumber = SM.getSpellingColumnNumber(SL); - - std::string FileNameString = SM.getFilename(SL).str(); - - XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); - MisraElement->SetText(Description.c_str()); - MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); - MisraElement->SetAttribute("FileName", FileNameString.c_str()); - MisraElement->SetAttribute("SpellingLineNumber", LineNumber); - MisraElement->SetAttribute("SpellingColumnNumber", ColumnNumber); - RootPointer->InsertEndChild(MisraElement); -} - -void XMLReport::XMLAddNode(std::string FilePath, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); - MisraElement->SetText(Description.c_str()); - MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); - MisraElement->SetAttribute("FileName", FilePath.c_str()); - RootPointer->InsertEndChild(MisraElement); -} - -void XMLReport::XMLAddNode(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - XMLElement* MisraElement = XMLReportDoc.NewElement("MisraDiag"); - MisraElement->SetText(Description.c_str()); - MisraElement->SetAttribute("Misra-C-2004Rule", MisraRule.c_str()); - MisraElement->SetAttribute("FileName", FileName.c_str()); - MisraElement->SetAttribute("SpellingLineNumber", Line); - MisraElement->SetAttribute("SpellingColumnNumber", Column); - RootPointer->InsertEndChild(MisraElement); -} - -bool XMLReport::isReportEmpty(void) -{ - return false; -} - -void XMLReport::SaveReport(void) -{ - if(this->isReportEmpty()) - { - return void(); - } - - XMLReportDoc.InsertEndChild(RootPointer); - - XMLError XMLErrorResult = XMLReportDoc.SaveFile("./misrareport.xml"); - - if (XMLErrorResult != XML_SUCCESS) - { - std::cerr << "could not write xml misra report.\n"; - } -} -/***************************************************End of XMLReport**************************************************/ -/*********************************************************************************************************************/ -/*****************************************************JSONReport******************************************************/ -JSONReport::JSONReport() {} - -void JSONReport::JSONCreateReport(void) -{ - JSONRepFile.open("./test/misrareport.json", std::ios::out); -} - -void JSONReport::JSONAddElement(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(1) of JSONAddElement is not valid."); - - FullSourceLoc FSL = ASTC->getFullLoc(SL); - - unsigned LineNumber = FSL.getSpellingLineNumber(); - unsigned ColumnNumber = FSL.getSpellingColumnNumber(); - - const SourceManager& SM = FSL.getManager(); - std::string FileNameString = SM.getFilename(SL).str(); - - json RepJ; - - RepJ["MisraDiag"]["Description"] = Description.c_str(); - RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); - RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); - RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; - RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; - - JSONRepFile << RepJ << std::endl; -} - -void JSONReport::JSONAddElement(FullSourceLoc FullSrcLoc, SourceLocation SL, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation passed as function parameter in an overload(2) of XMLAddNode is not valid."); - - unsigned LineNumber = FullSrcLoc.getSpellingLineNumber(); - unsigned ColumnNumber = FullSrcLoc.getSpellingColumnNumber(); - - const SourceManager& SM = FullSrcLoc.getManager(); - std::string FileNameString = SM.getFilename(SL).str(); - - json RepJ; - - RepJ["MisraDiag"]["Description"] = Description.c_str(); - RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); - RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); - RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; - RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; - - JSONRepFile << RepJ << std::endl; -} - -void JSONReport::JSONAddElement(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description) -{ - SL = SM.getSpellingLoc(SL); - - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - unsigned LineNumber = SM.getSpellingLineNumber(SL); - unsigned ColumnNumber = SM.getSpellingColumnNumber(SL); - - std::string FileNameString = SM.getFilename(SL).str(); - - json RepJ; - - RepJ["MisraDiag"]["Description"] = Description.c_str(); - RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); - RepJ["MisraDiag"]["FileName"] = FileNameString.c_str(); - RepJ["MisraDiag"]["SpellingLineNumber"] = LineNumber; - RepJ["MisraDiag"]["SpellingColumnNumber"] = ColumnNumber; - - JSONRepFile << RepJ << std::endl; -} - -void JSONReport::JSONAddElement(std::string FilePath, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - json RepJ; - - RepJ["MisraDiag"]["Description"] = Description.c_str(); - RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); - RepJ["MisraDiag"]["FileName"] = FilePath.c_str(); - - - JSONRepFile << RepJ << std::endl; -} - -void JSONReport::JSONAddElement(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description) -{ - //assert(SL.isValid() && "SourceLocation Acquired by SourceManager in an overload(3) of XMLAddNode is not valid."); - - json RepJ; - - RepJ["MisraDiag"]["Description"] = Description.c_str(); - RepJ["MisraDiag"]["Misra-C-2004Rule"] = MisraRule.c_str(); - RepJ["MisraDiag"]["FileName"] = FileName.c_str(); - RepJ["MisraDiag"]["SpellingLineNumber"] = Line; - RepJ["MisraDiag"]["SpellingColumnNumber"] = Column; - - JSONRepFile << RepJ << std::endl; -} - -void JSONReport::CloseReport(void) -{ - JSONRepFile.close(); -} -/*********************************************************************************************************************/ -/*************************************************End Of JSONReport***************************************************/ -/*********************************************************************************************************************/ - -/*********************************************************************************************************************/ -/*End of namespace Devi*/ -/*********************************************************************************************************************/ -} -/*********************************************************************************************************************/ -/*last line intentionally left blank.*/ - diff --git a/mutator_report.h b/mutator_report.h deleted file mode 100644 index ad3b843..0000000 --- a/mutator_report.h +++ /dev/null @@ -1,117 +0,0 @@ - -/***************************************************Project Mutator****************************************************/ -//-*-c++-*- -/*********************************************************************************************************************/ -/*first line intentionally left blank*/ -/*Copyright (C) 2017 Farzad Sadeghi - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ -/*********************************************************************************************************************/ -/*inclusion guard*/ -#ifndef MUTATOR_REPORT_H -#define MUTATOR_REPORT_H -/*********************************************************************************************************************/ -/*inclusion directives*/ -#include -#include -#include "clang/AST/AST.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "tinyxml2/tinyxml2.h" -/*********************************************************************************************************************/ -using namespace clang; -using namespace tinyxml2; -/*********************************************************************************************************************/ -namespace Devi { -/*********************************************************************************************************************/ - class XMLReportBase - { - public: - XMLReportBase(); - virtual ~XMLReportBase(); - - void CreateReport(void); - - virtual void AddNode(void) = 0; - - void SaveReport(const char*); - - protected: - XMLDocument Doc; - XMLElement* RootPointer; - }; -/*********************************************************************************************************************/ - /*@DEVI- for both report classes, if the program gets terminated, since the destructor does not close - the report files, what happens to them is implementation-defined in case of let's say an exit, but since - we erase the files everytime a new instance of mutator-lvl0 is called, we are fine. or so i think.*/ - /*@DEVI- in case of a crash, the XML report will only hold the base node, while the JSON report will - contain all the reports up until the crash. tinyxml2 writes the nodes to file on SaveFile which is - called in SaveReport so that's why.*/ - class XMLReport - { - public: - XMLReport(); - ~XMLReport(); - - void XMLCreateReport(void); - void XMLAddNode(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description); - /*overloaded for rule checks that announce the result on onendoftranslation instead of run - since they dont have access to matchresult or astcontext.*/ - void XMLAddNode(FullSourceLoc FSL, SourceLocation SL, std::string MisraRule, std::string Description); - /*another overload to support the xml output for PPCallbacks.*/ - void XMLAddNode(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description); - - void XMLAddNode(std::string FilePath, std::string MisraRule, std::string Description); - - void XMLAddNode(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description); - - bool isReportEmpty(void); - - void SaveReport(void); - - private: - XMLDocument XMLReportDoc; - XMLElement* RootPointer; - }; -/*********************************************************************************************************************/ - class JSONReport - { - public: - JSONReport(); - - void JSONCreateReport(void); - void JSONAddElement(ASTContext* ASTC, SourceLocation SL, std::string MisraRule, std::string Description); - /*overload for checks that announce the result in onendoftranslation unit.*/ - void JSONAddElement(FullSourceLoc FSL, SourceLocation SL, std::string MisraRule, std::string Description); - /*overload for PPCallbacks.*/ - void JSONAddElement(const SourceManager &SM, SourceLocation SL, std::string MisraRule, std::string Description); - - void JSONAddElement(std::string FilePath, std::string MisraRule, std::string Description); - - void JSONAddElement(unsigned Line, unsigned Column, std::string FileName, std::string MisraRule, std::string Description); - - void CloseReport(void); - - private: - std::ofstream JSONRepFile; - }; -/*********************************************************************************************************************/ -/*********************************************************************************************************************/ -} //end of namespace devi -#endif -/*********************************************************************************************************************/ -/*last line intentionally left blank.*/ - diff --git a/obfuscator/makefile b/obfuscator/makefile index f1ab5ab..fda9c20 100644 --- a/obfuscator/makefile +++ b/obfuscator/makefile @@ -28,7 +28,7 @@ LLVM_CONF?=llvm-config LLVM_CXX_FLAGS=$(shell $(LLVM_CONF) --cxxflags) LLVM_CXX_FLAGS+=-I$(shell $(LLVM_CONF) --src-root)/tools/clang/include\ -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include\ - -stdlib=libstdc++ -std=c++17 + -stdlib=libstdc++ -std=c++17 -fexceptions LLVM_LD_FLAGS=-Wl,--start-group -lclangAST -lclangAnalysis -lclangBasic\ -lclangDriver -lclangEdit -lclangFrontend -lclangFrontendTool\ -lclangLex -lclangParse -lclangSema -lclangEdit -lclangASTMatchers\ @@ -76,21 +76,27 @@ LD_FLAGS+=$(EXTRA_LD_FLAGS) all:$(TARGET) -everything:$(TARGET) A ASM SO $(TARGET)-static $(TARGET)-dbg TAGS $(TARGET)-cov +everything:$(TARGET) A ASM SO $(TARGET)-dbg TAGS $(TARGET)-cov depend:.depend .depend:$(SRCS) rm -rf .depend $(CXX) -MM $(CXX_FLAGS) $^ > ./.depend - echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[a-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend - echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[a-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend -include ./.depend -./keccak-tiny/.o:./keccak-tiny/.c +./keccak-tiny/%.o:./keccak-tiny/%.c $(CC) $(CFLAGS) -c $< -o $@ +./keccak-tiny/%.ocov:./keccak-tiny/%.c + $(CC) $(CFLAGS) $(COV_CXX) -c $< -o $@ + +./keccak-tiny/%.odbg:./keccak-tiny/%.c + $(CC) $(CFLAGS) -g -c $< -o $@ + .cpp.o: $(CXX) $(CXX_FLAGS) -c $< -o $@ @@ -100,15 +106,16 @@ depend:.depend %.ocov:%.cpp $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ -$(TARGET): $(TARGET).o ../mutator_aux.o ./keccak-tiny/keccak-tiny.o +$(TARGET): $(TARGET).o ../m0/mutator_aux.o ./keccak-tiny/keccak-tiny.o $(CXX) $^ $(LD_FLAGS) -o $@ -$(TARGET)-static: $(TARGET).o ../mutator_aux.o ./keccak-tiny/keccak-tiny.o + +$(TARGET)-static: $(TARGET).o ../m0/mutator_aux.o ./keccak-tiny/keccak-tiny.o $(CXX) $^ $(LD_FLAGS) -static -o $@ -$(TARGET)-dbg: $(TARGET).odbg ../mutator_aux.o ./keccak-tiny/keccak-tiny.o +$(TARGET)-dbg: $(TARGET).odbg ../m0/mutator_aux.odbg ./keccak-tiny/keccak-tiny.odbg $(CXX) $^ $(LD_FLAGS) -g -o $@ -$(TARGET)-cov: $(TARGET).ocov ../mutator_aux.o ./keccak-tiny/keccak-tiny.o +$(TARGET)-cov: $(TARGET).ocov ../m0/mutator_aux.ocov ./keccak-tiny/keccak-tiny.ocov $(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ cov: @@ -135,17 +142,17 @@ tags:$(SRCS) %.dis: %.o objdump -r -d -M intel -S $< > $@ -$(TARGET).so: $(TARGET).o ../mutator_aux.o ./keccak-tiny/keccak-tiny.o +$(TARGET).so: $(TARGET).o ../m0/mutator_aux.o ./keccak-tiny/keccak-tiny.o $(CXX) $^ $(LD_FLAGS) -shared -o $@ -$(TARGET).a: $(TARGET).o ../mutator_aux.o ./keccak-tiny/keccak-tiny.o +$(TARGET).a: $(TARGET).o ../m0/mutator_aux.o ./keccak-tiny/keccak-tiny.o ar rcs $(TARGET).a $(TARGET).o clean: - rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov ./keccak-tiny/*.o + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov ./keccak-tiny/*.o ./keccak-tiny/*.ocov ./keccak-tiny/*.odbg deepclean: - rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so tags $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov FILE*.cpp FILE*.hpp ./keccak-tiny/*.o + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so tags $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov FILE*.cpp FILE*.hpp ./keccak-tiny/*.o ./keccak-tiny/*.ocov ./keccak-tiny/*.odbg rm .depend help: diff --git a/obfuscator/obfuscator.cpp b/obfuscator/obfuscator.cpp index 7920535..9ab7310 100644 --- a/obfuscator/obfuscator.cpp +++ b/obfuscator/obfuscator.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* /**********************************************************************************************************************/ /*included modules*/ /*project headers*/ -#include "../mutator_aux.h" +#include "../m0/mutator_aux.h" #include "./keccak-tiny/keccak-tiny.hpp" /*standard headers*/ #include diff --git a/safercpp/makefile b/safercpp/makefile index 57ef94d..d4ba05f 100644 --- a/safercpp/makefile +++ b/safercpp/makefile @@ -1,40 +1,166 @@ +TARGET=safercpp-arr +SHELL=bash +SHELL?=bash +CC=clang +CC?=clang +CFLAGS=-fpic -std=c11 +CXX=clang++ +CXX?=clang++ +CXX_FLAGS=-fpic +CXX_EXTRA?= +CTAGS_I_PATH?=./ +LD_FLAGS= +EXTRA_LD_FLAGS?= +ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer +ADD_SANITIZERS_LD= -g -fsanitize=address +MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer +MEM_SANITIZERS_LD= -g -fsanitize=memory +UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer +UB_SANITIZERS_LD= -g -fsanitize=undefined +COV_CXX= -fprofile-instr-generate -fcoverage-mapping +COV_LD= -fprofile-instr-generate +# BUILD_MODES are=RELEASE(default), DEBUG,ADDSAN,MEMSAN,UBSAN +BUILD_MODE?=RELEASE +OBJ_LIST:=$(patsubst %.cpp, %.o, $(wildcard *.cpp)) +ASM_LIST:=$(patsubst %.cpp, %.dis, $(wildcard *.cpp)) -######################################INCLUDES################################# -include ../macros.mk - -#######################################VARS#################################### -CXX_FLAGS+=-frtti -SFCPP01=safercpp-arr -SRCS=$(wildcard *.cpp) +LLVM_CONF?=llvm-config ifeq ($(shell $(LLVM_CONF) --has-rtti), NO) $(error your llvm-config says you dont have rtti. you cant build safercpparr without rtti support.) endif -######################################RULES#################################### -.DEFAULT: all +LLVM_CXX_FLAGS=$(shell $(LLVM_CONF) --cxxflags) +LLVM_CXX_FLAGS+=-I$(shell $(LLVM_CONF) --src-root)/tools/clang/include\ + -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include\ + -stdlib=libstdc++ -std=c++17 -frtti -fexceptions +LLVM_LD_FLAGS=-Wl,--start-group -lclangAST -lclangAnalysis -lclangBasic\ + -lclangDriver -lclangEdit -lclangFrontend -lclangFrontendTool\ + -lclangLex -lclangParse -lclangSema -lclangEdit -lclangASTMatchers\ + -lclangRewrite -lclangRewriteFrontend -lclangStaticAnalyzerFrontend\ + -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore\ + -lclangSerialization -lclangToolingCore -lclangTooling -lstdc++\ + -lLLVMRuntimeDyld -lm -Wl,--end-group +LLVM_LD_FLAGS+=$(shell $(LLVM_CONF) --ldflags --libs --system-libs) + +CXX_FLAGS+=$(LLVM_CXX_FLAGS) +LD_FLAGS+=$(LLVM_LD_FLAGS) -.PHONY: all clean help +#MAKEFLAGS+=--warn-undefined-variables +ifeq ($(BUILD_MODE), ADDSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(ADD_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD) +endif -all: $(SFCPP01) +ifeq ($(BUILD_MODE), MEMSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(MEM_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD) +endif -%cpp:.depend +ifeq ($(BUILD_MODE), UBSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(UB_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD) +endif + +SRCS:=$(wildcard *.cpp) +CXX_FLAGS+=$(CXX_EXTRA) +LD_FLAGS+=$(EXTRA_LD_FLAGS) + +.DEFAULT:all + +.PHONY:all clean help ASM SO TAGS + +all:$(TARGET) + +everything:$(TARGET) ASM SO A $(TARGET)-dbg TAGS $(TARGET)-cov + +depend:.depend .depend:$(SRCS) + rm -rf .depend $(CXX) -MM $(CXX_FLAGS) $^ > ./.depend + echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\_\-]+\.odbg/\n&/g' >> ./.depend + echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\_\-]+\.ocov/\n&/g' >> ./.depend --include .depend +-include ./.depend .cpp.o: $(CXX) $(CXX_FLAGS) -c $< -o $@ -$(SFCPP01): $(SFCPP01).o ../mutator_aux.o +%.odbg:%.cpp + $(CXX) $(CXX_FLAGS) -g -c $< -o $@ + +%.ocov:%.cpp + $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ + +$(TARGET): $(TARGET).o ../m0/mutator_aux.o $(CXX) $^ $(LD_FLAGS) -o $@ +$(TARGET)-static: $(TARGET).o ../m0/mutator_aux.o + $(CXX) $^ $(LD_FLAGS) -static -o $@ + +$(TARGET)-dbg: $(TARGET).odbg ../m0/mutator_aux.odbg + $(CXX) $^ $(LD_FLAGS) -g -o $@ + +$(TARGET)-cov: $(TARGET).ocov ../m0/mutator_aux.ocov + $(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +cov: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov show $(TARGET)-cov -instr-profile=default.profdata + +covrep: + @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata + @llvm-cov report $(TARGET)-cov -instr-profile=default.profdata + +ASM:$(ASM_LIST) + +SO:$(TARGET).so + +A:$(TARGET).a + +TAGS:tags + +tags:$(SRCS) + $(shell $(CXX) -c $(shell $(LLVM_CONF) --cxxflags) -I$(shell $(LLVM_CONF) --src-root)/tools/clang/include -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include -I $(CTAGS_I_PATH) -M $(SRCS)|\ + sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\ + ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q) + +%.dis: %.o + objdump -r -d -M intel -S $< > $@ + +$(TARGET).so: $(TARGET).o ../mutator_aux.o + $(CXX) $^ $(LD_FLAGS) -shared -o $@ + +$(TARGET).a: $(TARGET).o ../mutator_aux.o + ar rcs $(TARGET).a $(TARGET).o clean: - rm -f *.o *~ $(SFCPP01) - rm ./.depend + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov + +deepclean: + rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so tags $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov FILE*.cpp FILE*.hpp + rm .depend help: - @echo 'There is help.' - @echo 'All is the defualt target.' - @echo 'Clean runs clean.' - @echo 'For a more complete and detaild list of BUILD_MODE and other things look at the main makefiles help under project root.' + @echo "--all is the default target, runs $(TARGET) target" + @echo "--everything will build everything" + @echo "--SO will generate the so" + @echo "--ASM will generate assembly files" + @echo "--TAGS will generate tags file" + @echo "--$(TARGET) builds the dynamically-linked executable" + @echo "--$(TARGET)-dbg will generate the debug build. BUILD_MODE should be set to DEBUG to work" + @echo "--$(TARGET)-static will statically link the executable to the libraries" + @echo "--$(TARGET)-cov is the coverage build" + @echo "--cov will print the line coverage report" + @echo "--covrep will print the coverage report" + @echo "--A will build the static library" + @echo "--TAGS will build the tags file" + @echo "--clean" + @echo "--deepclean will clean almost everything" diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp index ee00e19..99bd3a5 100644 --- a/safercpp/safercpp-arr.cpp +++ b/safercpp/safercpp-arr.cpp @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* /*included modules*/ /*Project Headers*/ #include "safercpp-arr.h" -#include "../mutator_aux.h" +#include "../m0/mutator_aux.h" /*Standard headers*/ #include #include diff --git a/tinyxml2/makefile b/tinyxml2/makefile index 3613b79..fd189dc 100644 --- a/tinyxml2/makefile +++ b/tinyxml2/makefile @@ -1,14 +1,19 @@ -######################################INCLUDES################################# include ../macros.mk +COV_CXX= -fprofile-instr-generate -fcoverage-mapping -######################################RULES#################################### -.DEFAULT: tinyxml2 +.DEFAULT: tinyxml2.o -.PHONY: tinyxml2 +everything: tinyxml2.o tinyxml2.ocov tinyxml2.odbg tinyxml2.o: tinyxml2.cpp - $(CXX) $(CXX_FLAGS) -c $< -o $@ + $(CXX) $(CXX_FLAGS) -c $< -o $@ + +tinyxml2.odbg: tinyxml2.cpp + $(CXX) $(CXX_FLAGS) -g -c $< -o $@ + +tinyxml2.ocov: tinyxml2.cpp + $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ clean: - rm -f *.o + rm -f *.o *.odbg *.ocov -- cgit v1.2.3