Skip to content
This repository was archived by the owner on May 14, 2024. It is now read-only.
This repository was archived by the owner on May 14, 2024. It is now read-only.

std::map is broken #10

Description

@stevenskevin

std::map is broken when compiling with ko-clang++. It works when using regular clang++.

Here's my test case ("test.cpp"). It sets up a std::map<std::string, std::string> and adds items to it one by one. At every step, it iterates over the whole map to print its contents, and also searches for a specific item with .find().

#include <cstdio>
#include <map>
#include <string>

typedef std::map<std::string, std::string> string_map_t;

void search_for_target(string_map_t &string_map) {
    printf("Current entries:");
    for (auto it = string_map.begin(); it != string_map.end(); ++it) {
        printf("  %s", it->first.c_str());
    }

    printf("\nSearching for \"key_target\": ");
    auto found = string_map.find("key_target");
    if (found != string_map.end()) {
        printf("Found! \"%s\"\n", found->second.c_str());
    } else {
        printf("Not found...\n");
    }
}

int main(int argc, const char *argv[]) {
    string_map_t string_map = {};
    search_for_target(string_map);

    string_map["key_A"] = "value_A";
    search_for_target(string_map);

    string_map["key_B"] = "value_B";
    search_for_target(string_map);

    string_map["key_target"] = "value_target";
    search_for_target(string_map);

    string_map["key_C"] = "value_C";
    search_for_target(string_map);

    string_map["key_D"] = "value_D";
    search_for_target(string_map);

    return 0;
}

Compile with standard clang++ and ko-clang++ commands (you can also optionally add -stdlib=libc++ -lc++ -lc++abi to the clang++ call to make it more like the ko-clang++ one, but it doesn't affect the overall outcome):

$ clang++ -o test test.cpp
$ ko-clang++ -o test_ko test.cpp

Output when compiled with regular clang++ (correct): The map grows as expected, and once "key_target" is added, .find() starts finding it:

$ ./test
Current entries:
Searching for "key_target": Not found...
Current entries:  key_A
Searching for "key_target": Not found...
Current entries:  key_A  key_B
Searching for "key_target": Not found...
Current entries:  key_A  key_B  key_target
Searching for "key_target": Found! "value_target"
Current entries:  key_A  key_B  key_C  key_target
Searching for "key_target": Found! "value_target"
Current entries:  key_A  key_B  key_C  key_D  key_target
Searching for "key_target": Found! "value_target"

Output when compiled with ko-clang++ (incorrect): Once an item is added to the map, iteration and searching both break. Iterators only ever yield the first item, and .find() always returns the most recently added item.

$ ./test_ko
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function mbtowc
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function __ctype_get_mb_cur_max
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function newlocale
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function pthread_cond_broadcast
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function mbtowc
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function __ctype_get_mb_cur_max
Current entries:
Searching for "key_target": Not found...
Current entries:  key_A
Searching for "key_target": Found! "value_A"
Current entries:  key_A
Searching for "key_target": Found! "value_B"
Current entries:  key_A
Searching for "key_target": Found! "value_target"
Current entries:  key_A
Searching for "key_target": Found! "value_C"
Current entries:  key_A
Searching for "key_target": Found! "value_D"
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function wcrtomb
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function wcrtomb
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function wcrtomb
==27699==WARNING: DataFlowSanitizer: call to uninstrumented function wcrtomb

My environment, if it helps: LLVM 6.0.1 in an Ubuntu 18.04 Docker container.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions