aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/Inline
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/Inline')
-rw-r--r--llvm/test/Transforms/Inline/attributes.ll42
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/test/Transforms/Inline/attributes.ll b/llvm/test/Transforms/Inline/attributes.ll
index 42b1a3a..55ab430 100644
--- a/llvm/test/Transforms/Inline/attributes.ll
+++ b/llvm/test/Transforms/Inline/attributes.ll
@@ -26,6 +26,10 @@ define i32 @sanitize_memtag_callee(i32 %i) sanitize_memtag {
ret i32 %i
}
+define i32 @sanitize_alloc_token_callee(i32 %i) sanitize_alloc_token {
+ ret i32 %i
+}
+
define i32 @safestack_callee(i32 %i) safestack {
ret i32 %i
}
@@ -58,6 +62,10 @@ define i32 @alwaysinline_sanitize_memtag_callee(i32 %i) alwaysinline sanitize_me
ret i32 %i
}
+define i32 @alwaysinline_sanitize_alloc_token_callee(i32 %i) alwaysinline sanitize_alloc_token {
+ ret i32 %i
+}
+
define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
ret i32 %i
}
@@ -184,6 +192,39 @@ define i32 @test_sanitize_memtag(i32 %arg) sanitize_memtag {
; CHECK-NEXT: ret i32
}
+; ---------------------------------------------------------------------------- ;
+
+; Can inline sanitize_alloc_token functions into a noattr function. The
+; attribute is *not* viral, otherwise may break code.
+define i32 @test_no_sanitize_alloc_token(i32 %arg) {
+; CHECK-LABEL: @test_no_sanitize_alloc_token(
+; CHECK-SAME: ) {
+; CHECK-NOT: call
+; CHECK: ret i32
+entry:
+ %x1 = call i32 @noattr_callee(i32 %arg)
+ %x2 = call i32 @sanitize_alloc_token_callee(i32 %x1)
+ %x3 = call i32 @alwaysinline_callee(i32 %x2)
+ %x4 = call i32 @alwaysinline_sanitize_alloc_token_callee(i32 %x3)
+ ret i32 %x4
+}
+
+; Can inline noattr functions into a sanitize_alloc_token function. If
+; inlinable noattr functions cannot be instrumented, they should be marked with
+; explicit noinline.
+define i32 @test_sanitize_alloc_token(i32 %arg) sanitize_alloc_token {
+; CHECK-LABEL: @test_sanitize_alloc_token(
+; CHECK-SAME: ) [[SANITIZE_ALLOC_TOKEN:.*]] {
+; CHECK-NOT: call
+; CHECK: ret i32
+entry:
+ %x1 = call i32 @noattr_callee(i32 %arg)
+ %x2 = call i32 @sanitize_alloc_token_callee(i32 %x1)
+ %x3 = call i32 @alwaysinline_callee(i32 %x2)
+ %x4 = call i32 @alwaysinline_sanitize_alloc_token_callee(i32 %x3)
+ ret i32 %x4
+}
+
define i32 @test_safestack(i32 %arg) safestack {
%x1 = call i32 @noattr_callee(i32 %arg)
%x2 = call i32 @safestack_callee(i32 %x1)
@@ -639,6 +680,7 @@ define i32 @loader_replaceable_caller() {
ret i32 %1
}
+; CHECK: attributes [[SANITIZE_ALLOC_TOKEN]] = { sanitize_alloc_token }
; CHECK: attributes [[SLH]] = { speculative_load_hardening }
; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
< 0) goto fail; gdbpy_initialize_gdb_readline (); if (gdbpy_initialize_auto_load () < 0 || gdbpy_initialize_values () < 0 || gdbpy_initialize_frames () < 0 || gdbpy_initialize_commands () < 0 || gdbpy_initialize_symbols () < 0 || gdbpy_initialize_symtabs () < 0 || gdbpy_initialize_blocks () < 0 || gdbpy_initialize_functions () < 0 || gdbpy_initialize_parameters () < 0 || gdbpy_initialize_types () < 0 || gdbpy_initialize_pspace () < 0 || gdbpy_initialize_objfile () < 0 || gdbpy_initialize_breakpoints () < 0 || gdbpy_initialize_finishbreakpoints () < 0 || gdbpy_initialize_lazy_string () < 0 || gdbpy_initialize_linetable () < 0 || gdbpy_initialize_thread () < 0 || gdbpy_initialize_inferior () < 0 || gdbpy_initialize_events () < 0 || gdbpy_initialize_eventregistry () < 0 || gdbpy_initialize_py_events () < 0 || gdbpy_initialize_event () < 0 || gdbpy_initialize_stop_event () < 0 || gdbpy_initialize_signal_event () < 0 || gdbpy_initialize_breakpoint_event () < 0 || gdbpy_initialize_continue_event () < 0 || gdbpy_initialize_inferior_call_pre_event () < 0 || gdbpy_initialize_inferior_call_post_event () < 0 || gdbpy_initialize_register_changed_event () < 0 || gdbpy_initialize_memory_changed_event () < 0 || gdbpy_initialize_exited_event () < 0 || gdbpy_initialize_thread_event () < 0 || gdbpy_initialize_new_objfile_event () < 0 || gdbpy_initialize_clear_objfiles_event () < 0 || gdbpy_initialize_arch () < 0 || gdbpy_initialize_xmethods () < 0 || gdbpy_initialize_unwind () < 0) goto fail; gdbpy_to_string_cst = PyString_FromString ("to_string"); if (gdbpy_to_string_cst == NULL) goto fail; gdbpy_children_cst = PyString_FromString ("children"); if (gdbpy_children_cst == NULL) goto fail; gdbpy_display_hint_cst = PyString_FromString ("display_hint"); if (gdbpy_display_hint_cst == NULL) goto fail; gdbpy_doc_cst = PyString_FromString ("__doc__"); if (gdbpy_doc_cst == NULL) goto fail; gdbpy_enabled_cst = PyString_FromString ("enabled"); if (gdbpy_enabled_cst == NULL) goto fail; gdbpy_value_cst = PyString_FromString ("value"); if (gdbpy_value_cst == NULL) goto fail; /* Release the GIL while gdb runs. */ PyThreadState_Swap (NULL); PyEval_ReleaseLock (); make_final_cleanup (finalize_python, NULL); gdb_python_initialized = 1; return; fail: gdbpy_print_stack (); /* Do not set 'gdb_python_initialized'. */ return; #endif /* HAVE_PYTHON */ } #ifdef HAVE_PYTHON /* Perform the remaining python initializations. These must be done after GDB is at least mostly initialized. E.g., The "info pretty-printer" command needs the "info" prefix command installed. This is the extension_language_ops.finish_initialization "method". */ static void gdbpy_finish_initialization (const struct extension_language_defn *extlang) { PyObject *m; char *gdb_pythondir; PyObject *sys_path; struct cleanup *cleanup; cleanup = ensure_python_env (get_current_arch (), current_language); /* Add the initial data-directory to sys.path. */ gdb_pythondir = concat (gdb_datadir, SLASH_STRING, "python", NULL); make_cleanup (xfree, gdb_pythondir); sys_path = PySys_GetObject ("path"); /* If sys.path is not defined yet, define it first. */ if (!(sys_path && PyList_Check (sys_path))) { #ifdef IS_PY3K PySys_SetPath (L""); #else PySys_SetPath (""); #endif sys_path = PySys_GetObject ("path"); } if (sys_path && PyList_Check (sys_path)) { PyObject *pythondir; int err; pythondir = PyString_FromString (gdb_pythondir); if (pythondir == NULL) goto fail; err = PyList_Insert (sys_path, 0, pythondir); Py_DECREF (pythondir); if (err) goto fail; } else goto fail; /* Import the gdb module to finish the initialization, and add it to __main__ for convenience. */ m = PyImport_AddModule ("__main__"); if (m == NULL) goto fail; gdb_python_module = PyImport_ImportModule ("gdb"); if (gdb_python_module == NULL) { gdbpy_print_stack (); /* This is passed in one call to warning so that blank lines aren't inserted between each line of text. */ warning (_("\n" "Could not load the Python gdb module from `%s'.\n" "Limited Python support is available from the _gdb module.\n" "Suggest passing --data-directory=/path/to/gdb/data-directory.\n"), gdb_pythondir); do_cleanups (cleanup); return; } if (gdb_pymodule_addobject (m, "gdb", gdb_python_module) < 0) goto fail; /* Keep the reference to gdb_python_module since it is in a global variable. */ do_cleanups (cleanup); return; fail: gdbpy_print_stack (); warning (_("internal error: Unhandled Python exception")); do_cleanups (cleanup); } /* Return non-zero if Python has successfully initialized. This is the extension_languages_ops.initialized "method". */ static int gdbpy_initialized (const struct extension_language_defn *extlang) { return gdb_python_initialized; } #endif /* HAVE_PYTHON */ #ifdef HAVE_PYTHON PyMethodDef python_GdbMethods[] = { { "history", gdbpy_history, METH_VARARGS, "Get a value from history" }, { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS, "execute (command [, from_tty] [, to_string]) -> [String]\n\ Evaluate command, a string, as a gdb CLI command. Optionally returns\n\ a Python String containing the output of the command if to_string is\n\ set to True." }, { "parameter", gdbpy_parameter, METH_VARARGS, "Return a gdb parameter's value" }, { "breakpoints", gdbpy_breakpoints, METH_NOARGS, "Return a tuple of all breakpoint objects" }, { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS, "Find the default visualizer for a Value." }, { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS, "Return the current Progspace." }, { "progspaces", gdbpy_progspaces, METH_NOARGS, "Return a sequence of all progspaces." }, { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS, "Return the current Objfile being loaded, or None." }, { "objfiles", gdbpy_objfiles, METH_NOARGS, "Return a sequence of all loaded objfiles." }, { "newest_frame", gdbpy_newest_frame, METH_NOARGS, "newest_frame () -> gdb.Frame.\n\ Return the newest frame object." }, { "selected_frame", gdbpy_selected_frame, METH_NOARGS, "selected_frame () -> gdb.Frame.\n\ Return the selected frame object." }, { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS, "stop_reason_string (Integer) -> String.\n\ Return a string explaining unwind stop reason." }, { "lookup_type", (PyCFunction) gdbpy_lookup_type, METH_VARARGS | METH_KEYWORDS, "lookup_type (name [, block]) -> type\n\ Return a Type corresponding to the given name." }, { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol, METH_VARARGS | METH_KEYWORDS, "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\ Return a tuple with the symbol corresponding to the given name (or None) and\n\ a boolean indicating if name is a field of the current implied argument\n\ `this' (when the current language is object-oriented)." }, { "lookup_global_symbol", (PyCFunction) gdbpy_lookup_global_symbol, METH_VARARGS | METH_KEYWORDS, "lookup_global_symbol (name [, domain]) -> symbol\n\ Return the symbol corresponding to the given name (or None)." }, { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile, METH_VARARGS | METH_KEYWORDS, "lookup_objfile (name, [by_build_id]) -> objfile\n\ Look up the specified objfile.\n\ If by_build_id is True, the objfile is looked up by using name\n\ as its build id." }, { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS, "Return the block containing the given pc value, or None." }, { "solib_name", gdbpy_solib_name, METH_VARARGS, "solib_name (Long) -> String.\n\ Return the name of the shared library holding a given address, or None." }, { "decode_line", gdbpy_decode_line, METH_VARARGS, "decode_line (String) -> Tuple. Decode a string argument the way\n\ that 'break' or 'edit' does. Return a tuple containing two elements.\n\ The first element contains any unparsed portion of the String parameter\n\ (or None if the string was fully parsed). The second element contains\n\ a tuple that contains all the locations that match, represented as\n\ gdb.Symtab_and_line objects (or None)."}, { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS, "parse_and_eval (String) -> Value.\n\ Parse String as an expression, evaluate it, and return the result as a Value." }, { "find_pc_line", gdbpy_find_pc_line, METH_VARARGS, "find_pc_line (pc) -> Symtab_and_line.\n\ Return the gdb.Symtab_and_line object corresponding to the pc value." }, { "post_event", gdbpy_post_event, METH_VARARGS, "Post an event into gdb's event loop." }, { "target_charset", gdbpy_target_charset, METH_NOARGS, "target_charset () -> string.\n\ Return the name of the current target charset." }, { "target_wide_charset", gdbpy_target_wide_charset, METH_NOARGS, "target_wide_charset () -> string.\n\ Return the name of the current target wide charset." }, { "string_to_argv", gdbpy_string_to_argv, METH_VARARGS, "string_to_argv (String) -> Array.\n\ Parse String and return an argv-like array.\n\ Arguments are separate by spaces and may be quoted." }, { "write", (PyCFunction)gdbpy_write, METH_VARARGS | METH_KEYWORDS, "Write a string using gdb's filtered stream." }, { "flush", (PyCFunction)gdbpy_flush, METH_VARARGS | METH_KEYWORDS, "Flush gdb's filtered stdout stream." }, { "selected_thread", gdbpy_selected_thread, METH_NOARGS, "selected_thread () -> gdb.InferiorThread.\n\ Return the selected thread object." }, { "selected_inferior", gdbpy_selected_inferior, METH_NOARGS, "selected_inferior () -> gdb.Inferior.\n\ Return the selected inferior object." }, { "inferiors", gdbpy_inferiors, METH_NOARGS, "inferiors () -> (gdb.Inferior, ...).\n\ Return a tuple containing all inferiors." }, {NULL, NULL, 0, NULL} }; #ifdef IS_PY3K struct PyModuleDef python_GdbModuleDef = { PyModuleDef_HEAD_INIT, "_gdb", NULL, -1, python_GdbMethods, NULL, NULL, NULL, NULL }; #endif #endif /* HAVE_PYTHON */