-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
aa267c8
commit 26abf5d
Showing
64 changed files
with
2,313 additions
and
2,298 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
[*.{ql,qll,qlref,dbscheme,qhelp,html,js,mjs,ts,json,yml,c,cpp,h,hpp}] | ||
[*] | ||
end_of_line = lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
# Improvements to C/C++ analysis | ||
|
||
## General improvements | ||
|
||
## New queries | ||
|
||
| **Query** | **Tags** | **Purpose** | | ||
|-----------------------------|-----------|--------------------------------------------------------------------| | ||
| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* | | ||
|
||
## Changes to existing queries | ||
|
||
| **Query** | **Expected impact** | **Change** | | ||
|----------------------------|------------------------|------------------------------------------------------------------| | ||
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. | | ||
|
||
|
||
## Changes to QL libraries | ||
|
||
* Added a hash consing library for structural comparison of expressions. | ||
# Improvements to C/C++ analysis | ||
|
||
## General improvements | ||
|
||
## New queries | ||
|
||
| **Query** | **Tags** | **Purpose** | | ||
|-----------------------------|-----------|--------------------------------------------------------------------| | ||
| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* | | ||
|
||
## Changes to existing queries | ||
|
||
| **Query** | **Expected impact** | **Change** | | ||
|----------------------------|------------------------|------------------------------------------------------------------| | ||
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. | | ||
|
||
|
||
## Changes to QL libraries | ||
|
||
* Added a hash consing library for structural comparison of expressions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<?eclipse version="3.2"?> | ||
<plugin> | ||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="semmlecode-cpp-queries"/> | ||
</extension> | ||
|
||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="com.semmle.code.cpp.library"/> | ||
</extension> | ||
|
||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="com.semmle.code.cpp.dbscheme"/> | ||
<path value="/semmlecode.cpp.dbscheme"/> | ||
</extension> | ||
</plugin> | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<?eclipse version="3.2"?> | ||
<plugin> | ||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="semmlecode-cpp-queries"/> | ||
</extension> | ||
|
||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="com.semmle.code.cpp.library"/> | ||
</extension> | ||
|
||
<extension point="com.semmle.plugin.qdt.ui.resources"> | ||
<name value="com.semmle.code.cpp.dbscheme"/> | ||
<path value="/semmlecode.cpp.dbscheme"/> | ||
</extension> | ||
</plugin> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,137 +1,137 @@ | ||
import sys | ||
import os.path | ||
import glob | ||
import re | ||
import json | ||
|
||
BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") | ||
END_TEMPLATE = re.compile(r"^\*/\s*$") | ||
|
||
def expand_template_params(args, param_arg_map): | ||
'''Given a list of template arguments that may reference template parameters | ||
of the current template, return a new list of template arguments with each | ||
parameter use replaced with the appropriate fully-qualified argument for | ||
that parameter.''' | ||
result = [] | ||
for arg in args: | ||
if arg in param_arg_map: | ||
result.append(param_arg_map[arg]) | ||
else: | ||
result.append(arg) | ||
|
||
return result | ||
|
||
def find_instantiation(module, args, templates): | ||
'''Given a template module and a set of template arguments, find the module | ||
name of the instantiation of that module with those arguments.''' | ||
template = templates[module] | ||
for instantiation in template["template_def"]["instantiations"]: | ||
if instantiation["args"] == args: | ||
return instantiation["name"] | ||
return None | ||
|
||
def instantiate_template(template, instantiation, root, templates): | ||
'''Create a single instantiation of a template.''' | ||
template_def = template["template_def"] | ||
output_components = instantiation["name"].split(".") | ||
output_path = root | ||
for component in output_components: | ||
output_path = os.path.join(output_path, component) | ||
output_path = output_path + ".qll" | ||
with open(output_path, "w") as output: | ||
output.write( | ||
""" | ||
/* | ||
* THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. | ||
* DO NOT EDIT MANUALLY. | ||
*/ | ||
""" % (template["name"].replace(".", "/") + ".qllt") | ||
) | ||
param_arg_map = {} | ||
for param_index in range(len(template_def["params"])): | ||
param = template_def["params"][param_index] | ||
arg = instantiation["args"][param_index] | ||
output.write("private import %s as %s // Template parameter\n" % (arg, param)) | ||
param_arg_map[param] = arg | ||
for import_record in template_def["imports"]: | ||
if "access" in import_record: | ||
output.write(import_record["access"] + " ") | ||
imported_module = find_instantiation(import_record["module"], | ||
expand_template_params(import_record["args"], param_arg_map), templates) | ||
output.write("import %s // %s<%s>\n" % | ||
( | ||
imported_module, | ||
import_record["module"], | ||
", ".join(import_record["args"]) | ||
) | ||
) | ||
|
||
output.writelines(template_def["body_lines"]) | ||
|
||
def generate_instantiations(template, root, templates): | ||
'''Create a .qll source file for each instantiation of the specified template.''' | ||
template_def = template["template_def"] | ||
if "instantiations" in template_def: | ||
for instantiation in template_def["instantiations"]: | ||
instantiate_template(template, instantiation, root, templates) | ||
|
||
def read_template(template_path, module_name): | ||
'''Read a .qllt template file from template_path, using module_name as the | ||
fully qualified name of the module.''' | ||
with open(template_path) as input: | ||
in_template = False | ||
template_text = "" | ||
template_def = None | ||
body_lines = [] | ||
for line in iter(input): | ||
if in_template: | ||
if END_TEMPLATE.match(line): | ||
template_def = json.loads(template_text) | ||
in_template = False | ||
else: | ||
template_text += line | ||
else: | ||
if BEGIN_TEMPLATE.match(line) and not template_def: | ||
in_template = True | ||
else: | ||
body_lines.append(line) | ||
|
||
if template_def: | ||
template_def["body_lines"] = body_lines | ||
|
||
result = { "name": module_name } | ||
if template_def: | ||
result["template_def"] = template_def | ||
return result | ||
|
||
def module_name_from_path_impl(path): | ||
(head, tail) = os.path.split(path) | ||
if head == "": | ||
return tail | ||
else: | ||
return module_name_from_path(head) + "." + tail | ||
|
||
def module_name_from_path(path): | ||
'''Compute the fully qualified name of a module from the path of its .qll[t] | ||
file. The path should be relative to the library root.''' | ||
(module_root, ext) = os.path.splitext(path) | ||
return module_name_from_path_impl(module_root) | ||
|
||
def main(): | ||
templates = {} | ||
|
||
root = sys.argv[1] | ||
for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): | ||
print(template_path) | ||
module_name = module_name_from_path(os.path.relpath(template_path, root)) | ||
print(module_name) | ||
template = read_template(template_path, module_name) | ||
templates[template["name"]] = template | ||
|
||
for name, template in templates.items(): | ||
if "template_def" in template: | ||
generate_instantiations(template, root, templates) | ||
|
||
if __name__ == "__main__": | ||
main() | ||
import sys | ||
import os.path | ||
import glob | ||
import re | ||
import json | ||
|
||
BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$") | ||
END_TEMPLATE = re.compile(r"^\*/\s*$") | ||
|
||
def expand_template_params(args, param_arg_map): | ||
'''Given a list of template arguments that may reference template parameters | ||
of the current template, return a new list of template arguments with each | ||
parameter use replaced with the appropriate fully-qualified argument for | ||
that parameter.''' | ||
result = [] | ||
for arg in args: | ||
if arg in param_arg_map: | ||
result.append(param_arg_map[arg]) | ||
else: | ||
result.append(arg) | ||
|
||
return result | ||
|
||
def find_instantiation(module, args, templates): | ||
'''Given a template module and a set of template arguments, find the module | ||
name of the instantiation of that module with those arguments.''' | ||
template = templates[module] | ||
for instantiation in template["template_def"]["instantiations"]: | ||
if instantiation["args"] == args: | ||
return instantiation["name"] | ||
return None | ||
|
||
def instantiate_template(template, instantiation, root, templates): | ||
'''Create a single instantiation of a template.''' | ||
template_def = template["template_def"] | ||
output_components = instantiation["name"].split(".") | ||
output_path = root | ||
for component in output_components: | ||
output_path = os.path.join(output_path, component) | ||
output_path = output_path + ".qll" | ||
with open(output_path, "w") as output: | ||
output.write( | ||
""" | ||
/* | ||
* THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'. | ||
* DO NOT EDIT MANUALLY. | ||
*/ | ||
""" % (template["name"].replace(".", "/") + ".qllt") | ||
) | ||
param_arg_map = {} | ||
for param_index in range(len(template_def["params"])): | ||
param = template_def["params"][param_index] | ||
arg = instantiation["args"][param_index] | ||
output.write("private import %s as %s // Template parameter\n" % (arg, param)) | ||
param_arg_map[param] = arg | ||
for import_record in template_def["imports"]: | ||
if "access" in import_record: | ||
output.write(import_record["access"] + " ") | ||
imported_module = find_instantiation(import_record["module"], | ||
expand_template_params(import_record["args"], param_arg_map), templates) | ||
output.write("import %s // %s<%s>\n" % | ||
( | ||
imported_module, | ||
import_record["module"], | ||
", ".join(import_record["args"]) | ||
) | ||
) | ||
|
||
output.writelines(template_def["body_lines"]) | ||
|
||
def generate_instantiations(template, root, templates): | ||
'''Create a .qll source file for each instantiation of the specified template.''' | ||
template_def = template["template_def"] | ||
if "instantiations" in template_def: | ||
for instantiation in template_def["instantiations"]: | ||
instantiate_template(template, instantiation, root, templates) | ||
|
||
def read_template(template_path, module_name): | ||
'''Read a .qllt template file from template_path, using module_name as the | ||
fully qualified name of the module.''' | ||
with open(template_path) as input: | ||
in_template = False | ||
template_text = "" | ||
template_def = None | ||
body_lines = [] | ||
for line in iter(input): | ||
if in_template: | ||
if END_TEMPLATE.match(line): | ||
template_def = json.loads(template_text) | ||
in_template = False | ||
else: | ||
template_text += line | ||
else: | ||
if BEGIN_TEMPLATE.match(line) and not template_def: | ||
in_template = True | ||
else: | ||
body_lines.append(line) | ||
|
||
if template_def: | ||
template_def["body_lines"] = body_lines | ||
|
||
result = { "name": module_name } | ||
if template_def: | ||
result["template_def"] = template_def | ||
return result | ||
|
||
def module_name_from_path_impl(path): | ||
(head, tail) = os.path.split(path) | ||
if head == "": | ||
return tail | ||
else: | ||
return module_name_from_path(head) + "." + tail | ||
|
||
def module_name_from_path(path): | ||
'''Compute the fully qualified name of a module from the path of its .qll[t] | ||
file. The path should be relative to the library root.''' | ||
(module_root, ext) = os.path.splitext(path) | ||
return module_name_from_path_impl(module_root) | ||
|
||
def main(): | ||
templates = {} | ||
|
||
root = sys.argv[1] | ||
for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True): | ||
print(template_path) | ||
module_name = module_name_from_path(os.path.relpath(template_path, root)) | ||
print(module_name) | ||
template = read_template(template_path, module_name) | ||
templates[template["name"]] = template | ||
|
||
for name, template in templates.items(): | ||
if "template_def" in template: | ||
generate_instantiations(template, root, templates) | ||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.