static void test_string_literals (gimple *stmt) { gcall *call = check_for_named_call (stmt, "__emit_string_literal_range", 4); if (!call) return; /* We expect an ADDR_EXPR with a STRING_CST inside it for the initial arg. */ tree t_addr_string = gimple_call_arg (call, 0); if (TREE_CODE (t_addr_string) != ADDR_EXPR) { error_at (call->location, "string literal required for arg 1"); return; } tree t_string = TREE_OPERAND (t_addr_string, 0); if (TREE_CODE (t_string) != STRING_CST) { error_at (call->location, "string literal required for arg 1"); return; } tree t_caret_idx = gimple_call_arg (call, 1); if (TREE_CODE (t_caret_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 2"); return; } int caret_idx = TREE_INT_CST_LOW (t_caret_idx); tree t_start_idx = gimple_call_arg (call, 2); if (TREE_CODE (t_start_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 3"); return; } int start_idx = TREE_INT_CST_LOW (t_start_idx); tree t_end_idx = gimple_call_arg (call, 3); if (TREE_CODE (t_end_idx) != INTEGER_CST) { error_at (call->location, "integer constant required for arg 4"); return; } int end_idx = TREE_INT_CST_LOW (t_end_idx); /* A STRING_CST doesn't have a location, but the ADDR_EXPR does. */ location_t strloc = EXPR_LOCATION (t_addr_string); location_t loc; substring_loc substr_loc (strloc, TREE_TYPE (t_string), caret_idx, start_idx, end_idx); const char *err = substr_loc.get_location (&loc); if (err) error_at (strloc, "unable to read substring location: %s", err); else emit_warning (loc); }
int os_thread_create( void (*run)(void *arg), void *arg, bool high_priority, struct OsThread ** out_thread) { *out_thread = NULL; struct OsThread *thread = allocate_zero<OsThread>(1); if (!thread) { os_thread_destroy(thread); return GenesisErrorNoMem; } thread->run = run; thread->arg = arg; #if defined(GENESIS_OS_WINDOWS) thread->handle = CreateThread(NULL, 0, run_win32_thread, thread, 0, &thread->id); if (!thread->handle) { os_thread_destroy(thread); return GenesisErrorSystemResources; } if (high_priority) { if (!SetThreadPriority(thread->handle, THREAD_PRIORITY_TIME_CRITICAL)) { emit_warning(WarningHighPriorityThread); } } #else int err; if ((err = pthread_attr_init(&thread->attr))) { os_thread_destroy(thread); return GenesisErrorNoMem; } thread->attr_init = true; if (high_priority) { int max_priority = sched_get_priority_max(SCHED_FIFO); if (max_priority == -1) { os_thread_destroy(thread); return GenesisErrorSystemResources; } if ((err = pthread_attr_setschedpolicy(&thread->attr, SCHED_FIFO))) { os_thread_destroy(thread); return GenesisErrorSystemResources; } struct sched_param param; param.sched_priority = max_priority; if ((err = pthread_attr_setschedparam(&thread->attr, ¶m))) { os_thread_destroy(thread); return GenesisErrorSystemResources; } } if ((err = pthread_create(&thread->id, &thread->attr, run_pthread, thread))) { if (err == EPERM && high_priority) { emit_warning(WarningHighPriorityThread); err = pthread_create(&thread->id, NULL, run_pthread, thread); } if (err) { os_thread_destroy(thread); return GenesisErrorNoMem; } } thread->running = true; #endif *out_thread = thread; return 0; }